Python 函数

1. 函数

1.1 文档注释

# 文档字符串注释,用三引号括起
def greet():
    """问候语"""
    print("Hello, world!")

1.2 参数示例

def greet(user_name):
    print(f"Hello, {user_name}!")

greet('Alan')

# 关键字实参: 传递给函数的键值对
greet(user_name='Alan')

传递列表

def greet_users(names):
    for name in names:
        print(f"Hello, {name}!")

usernames = ['Alan', 'Alice']
greet_users(usernames)

1.3 默认值

def greet(user_name, pet_name='dog'):
    print(f"Hello, {user_name}!, your pet name is {pet_name}!")

greet(user_name='Alan')
greet('Alan')
greet('Alan', 'One')

1.4 不定长参数

任意数量实参

def greet(*user_name):
    print(user_name)

greet('Alan')
greet('Alan', 'Alice')

任意数量的键值对

def build_person(first_name, last_name, **user_info):
    user_info['first_name'] = first_name
    user_info['last_name'] = last_name
    return user_info

1.5 参数(/)

def __new__(cls, func, /, *args, **keywords):
    ...

从 Python 3.8 开始引入/, 位于 / 之前的参数是位置参数

1.6 参数(*)

def __init__(self, origin, params, *, inst=True, special=False, name=None):
    ...

参数 * 后的参数是关键字参数
比如,参数必须传flag=true 而不是 true

1.7 Ellipsis(...)

... 表示函数的实现尚未完成或省略

场景:
占位符:在代码中表示未实现的部分,类似于 pass

def unfinished_function():
    ...  # 表示函数未实现

2. 返回值

def build_person(first_name, last_name):
    person = {'first_name': first_name, 'last_name': last_name}
    return person

person = build_person('Alan', 'Turing')
print(person)

2.2 多个返回值

函数可以返回多个值,实际上是返回了一个元组(tuple)

def multi_return():
    return 'Alice', 20

name, age = multi_return()
print(f'{name} is {age} years old')

示例2:

def multiple_return_values():
    return 1, 2, 3, 4, 5

a, *b, c = multiple_return_values()
print(f'a={a}, b={b}, c={c}') # a=1, b=[2, 3, 4], c=5
print(f'type(b): {type(b)}') # a=1, b=[2, 3, 4], c=5

默认情况下,*b 会生成一个列表

将列表转换为元组

b = tuple(b)
print(f'a={a}, b={b}, c={c}')

3. 函数注解(Function Annotations)

def foo(a: expression, b: expression = def_value) -> expression:
    ...

冒号 : 是参数的类型建议符
等号= 指定参数的默认值
箭头 -> 后是函数返回值的类型建议符

3.1 参数分析

typing.py 模块提供了一系列类型提示(type hints),可用于添加类型注解

# 任何类型
Any = _SpecialForm('Any', doc="""""")

NoReturn = _SpecialForm('NoReturn', doc="""""")

ClassVar = _SpecialForm('ClassVar', doc="""""")

Final = _SpecialForm('Final', doc="""""")

# 联合类型,表示多个类型的联合,可以是这些类型中的任意一种。
Union = _SpecialForm('Union', doc="""""")

# 可选类型 Optional[X] is equivalent to Union[X, None].
Optional = _SpecialForm('Optional', doc="""""")

Literal = _SpecialForm('Literal', doc="""""")

参数示例:

def pipeline(
    task: str = None,
    model: Optional[Union[str, "PreTrainedModel", "TFPreTrainedModel"]] = None,
    config: Optional[Union[str, PretrainedConfig]] = None,
    tokenizer: Optional[Union[str, PreTrainedTokenizer, "PreTrainedTokenizerFast"]] = None,
    feature_extractor: Optional[Union[str, PreTrainedFeatureExtractor]] = None,
    image_processor: Optional[Union[str, BaseImageProcessor]] = None,
    processor: Optional[Union[str, ProcessorMixin]] = None,
    framework: Optional[str] = None,
    revision: Optional[str] = None,
    use_fast: bool = True,
    token: Optional[Union[str, bool]] = None,
    device: Optional[Union[int, str, "torch.device"]] = None,
    device_map=None,
    torch_dtype=None,
    trust_remote_code: Optional[bool] = None,
    model_kwargs: Dict[str, Any] = None,
    pipeline_class: Optional[Any] = None,
    **kwargs,
) -> Pipeline:
  ...

4. 存根文件(.pyi)

.pyi 文件是 Python 的存根(stub)文件,主要用于类型提示(type hints)

如果某一行的左边有 * 号标识,则说明这一行(可以是类、属性或函数)在存根文件中有定义,可以点击 * 号跳转到该文件对应的存根文件

示例:列表转换为元组

list = [1, 2, 3]
tup = tuple(list)

分析:

# builtins.py

class tuple(object):
    
    @staticmethod
    def __new__(*args, **kwargs):
        pass

点击方法前面的 * 号,跳转到 .pyi 文件

# builtins.pyi

_T_co = TypeVar("_T_co", covariant=True)

class tuple(Sequence[_T_co], Generic[_T_co]):
    def __new__(cls: type[Self], __iterable: Iterable[_T_co] = ...) -> Self: ...

type[Self]: 当前类的类型
Iterable[_T_co]: 可迭代对象,其元素类型为协变类型变量(_T_co)
-> Self: 返回一个当前类的实例

协变类型变量 (_T_co) 允许指定一个类型参数,它可以接受其定义的类型或该类型的子类
类似于 Java 的上界通配符 (? extends T)

TypeVar 允许创建泛型函数或类
分析 TypeVar("_T_co", covariant=True)

# typing.py

class TypeVar(_Final, _Immutable, _root=True):

    def __init__(self, name, *constraints, bound=None,
                 covariant=False, contravariant=False):
        ...

4.2 存根文件中的(...)

Axes.plot(self, *args, scalex=True, scaley=True, data=None, **kwargs):

def plot(
    self,
    *args: float | ArrayLike | str,
    scalex: bool = ...,
    scaley: bool = ...,
    data=...,
    **kwargs
) -> list[Line2D]: ...

... 表示这个默认值在实际代码中定义,而不是在这里

5. 其他

5.1 装饰器

装饰器:@_api.make_keyword_only 用于控制函数参数的调用方式
@_api.make_keyword_only("3.3", "sharex")

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容