这里是白哥,今天给大家带来Python参数的详细介绍
对于Python参数,相信大家都不陌生,基本的使用用法也知道
def foo(a,b,c=1)
pass
但是对于更复杂的情况,或许看到就有点蒙了,比如langchain里面的invoke函数,各种*、**
可能初学者看得会比较凌乱,为此,我就详细给大家介绍以下python的参数吧~~~
def invoke(
self,
input: LanguageModelInput,
config: Optional[RunnableConfig] = None,
*,
stop: Optional[list[str]] = None,
**kwargs: Any,
) -> BaseMessage:
pass
参数的类型
狭义角度上:python参数可以分为五类(函数定义的角度)
- 位置参数
- 默认参数
- 可变参数
- 命名关键字参数
- 关键字参数
位置参数
狭义上:从函数定义的角度
大家熟知的def fun(a,b)
中a和b就是位置参数,他们的排布是固定好位置的,但我们调用函数时,可以直接写fun(1,2)
这样1,2就对应a=1、b=2的位置,也就是位置参数这个叫法的由来
默认参数
def(a,b,c=5)
c就是默认参数,因为它有个默认值
可变参数
def(a,b,*c)
c就是可变参数,主要特征就是有个*,这个*会对多个参数进行装包
def fun1(a,b,c=5):
print('a =', a, 'b =', b, 'c =', c)
def fun2(a,b,*c):
print('a =', a, 'b =', b, 'c =', c)
fun1(2,3,(1,2,3))
fun2(2,3,1,2,3)
fun2(2,3,*(1,2,3))
fun1(2,3,*(1,2,3))
-----------------------------------------------------
output:
a = 2 b = 3 c = (1, 2, 3) (1)
a = 2 b = 3 c = (1, 2, 3) (2)
a = 2 b = 3 c = (1, 2, 3) (3)
fun1() takes from 2 to 3 positional arguments but 5 were given (4)
(1)python是默认可以传入任意对象的,当我们传递一个数组作为默认参数的值是可以的
(2)但输入参数多于函数参数个数,可以看到对于可变参数来说,就是将多的全部打包为一个序列 (这其实是变成了一个参数,等价于(1)了)
(3)两个*的含义是不同的,一个是对序列解包,一个是多的参数装包
(4) 多个参数超出位置参数的个数时,是会报错的,因为位置参数只有3个
命名关键字参数
def f2(a, b, c=0, *, d):
print('a =', a, 'b =', b, 'c =', c, 'd =', d)
def f3(a, b, c=0, *arg, d=1):
print('a =', a, 'b =', b, 'c =', c, "arg = ",arg, 'd =', d)
f2(1,2,3,d=5)
a = 1 b = 2 c = 3 d = 5
f3(1,2,3,4,5,6,d=5)
a = 1 b = 2 c = 3 arg = (4, 5, 6) d = 5
f2(1,2,d=5)
a = 1 b = 2 c = 0 d = 5
f3(1,2,d=5)
a = 1 b = 2 c = 0 arg = () d = 5
f3(1,2)
a = 1 b = 2 c = 0 arg = () d = 1 (1)
f2(1,2)
missing 1 required keyword-only argument: 'd' (2)
f2、f3中的d都属于命名关键字参数的定义:在可变长序列或*后
命名关键字参数没有预设值的情况下,引用时必须要设置 (2)
命名关键字预设值的情况下,其实就是可以接在可变参数后的默认参数 (1)但区别就是我们引用时需要显式的写出其变量名
def f2(a, b, c=0, *, d):
print('a =', a, 'b =', b, 'c =', c, 'd =', d)
f2(3,4,1,d=4)
a = 3 b = 4 c = 1 d = 4
f2(3,4,1,4)
f2() takes from 2 to 3 positional arguments but 4 were given
!!这个4不会向默认参数一样自动放置到该位置上,所以需要显示地说明d=XX
关键字参数
def f4(a, b, c=0, *, d, **kw):
print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
kw就是关键字参数,就是不限定key的键值对参数,类似变长序列的装包,关键字参数就是将k1=v1,k2=v2装为一个字典 {“k1”:v1,“k2”:v2}
对应的解包操作也是**
f4(1,2,3,4,5,6,kw1=3,w2=6,d=6)
> a = 1 b = 2 c = 3 args (4, 5, 6) d = 6 kw = {'kw1': 3, 'w2': 6}
kw = {"1":1,"4":2}
f4(1,2,("1","3","4"),d=5)
> a = 1 b = 2 c = ('1', '3', '4') args () d = 5 kw = {}
kw = {"1":1,"4":2}
f4(1,2,*(1,3,4),d=5,**kw)
> a = 1 b = 2 c = 1 args (3, 4) d = 5 kw = {'1': 1, '4': 2}
广义角度上的的参数类型
从函数调用的角度,只有位置参数以及关键字参数
其实可以看到,就算是可变参数或者关键字参数,本质也是通过装包使得多个参数变为一个,那其实不同点在于要不要写 = ,可以这么理解,能知道自己位置的就是位置参数,不能知道自己的位置的,就需要加 = 来确认自己的位置。
所以这就引申出 位置参数不能在关键参数之后 因为否则的话位置参数就不知道自己的位置
def fun(a,b,c=1)
pass
fun(1,2,3) --都是位置参数
fun(1,2,c=3) --c=3为关键字参数
fun(c=3(1,2)) -- SyntaxError: positional argument follows keyword argument
函数调用时,不写成fun(a=1,b=2)
的都叫做位置参数,也就是说直接排列上去fun(a,b,c=1)
a和b就叫位置参数
位置参数通常在调用时是写在最前的
位置参数不能在关键参数之后,否则位置参数就不知道自己的位置了
最开始的问题
def invoke(
self,
input: LanguageModelInput, # 位置参数
config: Optional[RunnableConfig] = None, # 默认参数
*,
stop: Optional[list[str]] = None, # 命名关键字参数 且需要调用时需要显式说明stop=xxx
**kwargs: Any, # 关键字参数
) -> BaseMessage:
pass
是不是就很清晰明了了,对于这个函数,我们调用时一定要有的就是 input 参数,其他的无所谓
当然,或许还有小伙伴有疑问 这些 : -> 是什么
其实 这些事一种提示机制,方便调用者调用时知道使用什么类型,: 表示某一类似
-> 表示返回值
当然也只是提示作用,并不是强制,比如下面代码 虽然这么写但是并不会报错
def fun6(a:int,b:bool=True)->str:
return b
fun6(True,2)
2
为了限制类型,更多的实在函数内部进行限制
::: :::::
from typing import (
TYPE_CHECKING,
Any,
Callable,
Literal,
Optional,
Union,
cast,
)
在 Python 中,使用类型提示(Type Hinting)时,像 c: Optional[bool] = 0 的语法表示参数 c 可以是一个布尔值或 None,并且默认为 0。不过,这并不会强制函数只接受布尔值或 None。实际上,Python 的类型提示并不是强制性的,它们只是为开发者和工具提供信息。
示例分析
from typing import Optional
def example_function(c: Optional[bool] = 0):
if c is None:
print("c is None")
elif c:
print("c is True")
else:
print("c is False")
可能的问题
类型检查工具:
只有在使用类型检查工具(如 mypy)时,才会对类型提示进行检查。如果 c 被赋予其他类型(比如字符串或整数),Python 本身不会抛出错误。
默认值问题:
0 是整数,虽然在布尔上下文中会被视为 False,但这并不意味着 c 的类型是布尔值。为了使类型更明确,您可以将默认值设置为 None:
def example_function(c: Optional[bool] = None):
运行时类型检查:
如果您想在运行时强制参数类型,可以手动检查类型:
def example_function(c: Optional[bool] = None):
if c is not None and not isinstance(c, bool):
raise TypeError("c must be a bool or None")
总结
类型提示:Optional[bool] 表示 c 可以是布尔值或 None,但不会强制执行。
强制类型:如果需要限制类型,您需要手动检查类型或使用类型检查工具。
默认值:使用 None 作为默认值可以避免混淆,确保类型更明确。