python:构造函数参数表示法
python: constructor argument notation
我学习了几个月 python。
通过金字塔教程后,我无法理解 init.py
中的一行
from pyramid.config import Configurator
from sqlalchemy import engine_from_config
from .models import (
DBSession,
Base,
)
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine)
Base.metadata.bind = engine
config = Configurator(settings=settings)
config.include('pyramid_chameleon')
config.add_static_view('static', 'static', cache_max_age=3600)
config.add_route('home', '/')
config.scan()
return config.make_wsgi_app()
我不知道配置器参数中的 settings=settings。
这说明了什么 python?
这意味着您正在将参数 settings 传递给 Configurator,其中包含一个名为 settings[=26 的变量=]
举个例子,你有一个函数:
def function_test(a=None, b=None, c=None):
pass
你可以这样称呼它:
c = "something"
function_test(c=c)
这意味着您将创建的变量 c 作为参数传递给函数 中的参数 c function_test
Python 函数支持关键字参数:
def add(a, b):
return a + b
add(a=1, b=2)
这发生在这里。
Configurator(settings=settings)
第一个settings
是Configurator
的__init__
中的参数名。第二个是当前名称中对象的名称 space.
这是说它正在传递本地名称 settings
作为 Configurator
中名为 settings
的参数。
对于 x=y
形式的函数或构造函数调用,x
是在 function/constructor 端本地使用的参数名称,而 y
是名称在来电方。在这种情况下,它们恰好是同一个名字。
Python 支持调用任何可调用对象(即函数、构造函数,甚至对象理解 __call__
方法)指定位置参数、命名参数,甚至两种类型的参数。
当您传递命名参数时,它们必须在位置参数之后(如果传递的话)。
因此您可以调用任何函数,例如:
def f(a, b):
return a + b
通过以下方式:
f(1, 2)
f(1, b=2)
f(a=1, b=2)
f(b=1, a=2) # Order doesn't matter among named arguments
而以下形式会触发错误:
f(a=1, 2) # Named arguments must appear AFTER positional arguments
f(1, a=2) # You are passing the same argument twice: one by position, one by name
因此,当您传递一个命名参数时,请确保您没有传递相同的参数两次(即也按位置),并检查参数名称是否存在(另外:如果记录了参数could/should名传千里,敬inheritance/override).
另外 Python支持传递*arguments
和**keyword_arguments
。这些是您可以以可变方式处理的附加参数,因为许多语言都支持它们。
*args
(名称无关紧要 - 它必须有一个星号才能成为位置可变参数;它是一个元组)保留剩余的 unmatched 位置参数(而不是位置参数意外出现 TypeError,这样的参数作为元素进入 *args
)。
**kwargs
(名称无关紧要 - 它必须有两个星号才能成为 named/keyword 可变参数;它是一个字典)包含剩余的 unmatched 命名参数(而不是为命名参数意外获取 TypeError,这样的参数作为元素进入 **kwargs
)。
所以,也许您会看到这样的函数:
def f(*args, **kwargs):
...
您可以使用任何您想要的参数来调用它:
f(1, 2, 3, a=4, b=5, c=6)
保持顺序:命名参数在位置参数之后。
您可以这样声明一个函数:
f(m1, m2, ..., o1=1, o2=2, ..., *args, **kwargs):
pass
了解以下内容:
- m1、m2、... 强制性:调用时,必须按照位置或名称填写。
- o1, o2, ... 是 可选的:当你调用时,你可以省略这些参数(省略它们意味着不按位置或按名称传递它们),并且它们将保留等号后的值(此类值在函数声明时计算 - 避免使用可变对象作为它们的值)。
- args 和 kwargs 是我之前向您解释的:任何按位置和名称不匹配的参数都会进入这些参数。有了这些特性,你就可以清楚地区分什么是形参,什么是实参。
- 所有这些参数都是可选的。您可以选择不使用强制性的,而只使用可选的。您可以选择不使用
*args
但使用 **kwargs
,依此类推。但是尊重声明中的顺序:强制,可选,*args
,**kwargs
。
当你调用方法并传递参数时语义非常不同所以要小心:
f(1) # passes a positional argument. Has nothing to do with the parameter being mandatory.
f(a=1) # passes a named argument. Has nothing to do with the parameter being optional.
f(**i) # UNPACKS the positional arguments. Has nothing to do with the function having a *args parameter, but *args will hold any unpacked -but unmatched- positional argument from i (which is any type of sequence or generator)
f(**d) # UNPACKS its values as named arguments. Has nothing to do with the function having a **kwargs parameter, but **kwargs will hold any unpacked -but unmatched- argument from d (which is a dict having string keys).
当你调用的时候,你可以随意传递它们,这与实际的方法签名无关(即预期的参数),但是 尊重参数的顺序:positional, named, *positionalUnpack, **keywordUnpack,否则你会得到一个很好的 TypeError
.
示例:
def f(a, b=1, *args, **kwargs):
pass
有效调用:
f(1) # a = 1, b = 2, args = (), kwargs = {}
f(*[1]) #a = 1, b = 2, args = (), kwargs = {}
f(*[3, 4]) #a = 3, b = 4, args = (), kwargs = {}
f(**{'a':1, 'b':3}) #a = 1, b=3, args = (), kwargs = {}
f(1, *[2, 3, 4], **{'c': 5}) #a = 1, b=2, args=(3, 4), kwargs = {'c': 5}
再次注意:
- 不要传递相同的参数两次(**解压参数与其他命名参数、位置参数或*解压参数之间会发生冲突)。
如果要将 *args 或 **kwargs 传递给 super
调用,请确保使用解包语法:
def my_method(self, a, b, *args, **kwargs):
super(MyClass, self).my_method(a+1, b+1, *args, **kwargs)
我学习了几个月 python。 通过金字塔教程后,我无法理解 init.py
中的一行from pyramid.config import Configurator
from sqlalchemy import engine_from_config
from .models import (
DBSession,
Base,
)
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine)
Base.metadata.bind = engine
config = Configurator(settings=settings)
config.include('pyramid_chameleon')
config.add_static_view('static', 'static', cache_max_age=3600)
config.add_route('home', '/')
config.scan()
return config.make_wsgi_app()
我不知道配置器参数中的 settings=settings。
这说明了什么 python?
这意味着您正在将参数 settings 传递给 Configurator,其中包含一个名为 settings[=26 的变量=]
举个例子,你有一个函数:
def function_test(a=None, b=None, c=None):
pass
你可以这样称呼它:
c = "something"
function_test(c=c)
这意味着您将创建的变量 c 作为参数传递给函数 中的参数 c function_test
Python 函数支持关键字参数:
def add(a, b):
return a + b
add(a=1, b=2)
这发生在这里。
Configurator(settings=settings)
第一个settings
是Configurator
的__init__
中的参数名。第二个是当前名称中对象的名称 space.
这是说它正在传递本地名称 settings
作为 Configurator
中名为 settings
的参数。
对于 x=y
形式的函数或构造函数调用,x
是在 function/constructor 端本地使用的参数名称,而 y
是名称在来电方。在这种情况下,它们恰好是同一个名字。
Python 支持调用任何可调用对象(即函数、构造函数,甚至对象理解 __call__
方法)指定位置参数、命名参数,甚至两种类型的参数。
当您传递命名参数时,它们必须在位置参数之后(如果传递的话)。
因此您可以调用任何函数,例如:
def f(a, b):
return a + b
通过以下方式:
f(1, 2)
f(1, b=2)
f(a=1, b=2)
f(b=1, a=2) # Order doesn't matter among named arguments
而以下形式会触发错误:
f(a=1, 2) # Named arguments must appear AFTER positional arguments
f(1, a=2) # You are passing the same argument twice: one by position, one by name
因此,当您传递一个命名参数时,请确保您没有传递相同的参数两次(即也按位置),并检查参数名称是否存在(另外:如果记录了参数could/should名传千里,敬inheritance/override).
另外 Python支持传递*arguments
和**keyword_arguments
。这些是您可以以可变方式处理的附加参数,因为许多语言都支持它们。
*args
(名称无关紧要 - 它必须有一个星号才能成为位置可变参数;它是一个元组)保留剩余的 unmatched 位置参数(而不是位置参数意外出现 TypeError,这样的参数作为元素进入 *args
)。
**kwargs
(名称无关紧要 - 它必须有两个星号才能成为 named/keyword 可变参数;它是一个字典)包含剩余的 unmatched 命名参数(而不是为命名参数意外获取 TypeError,这样的参数作为元素进入 **kwargs
)。
所以,也许您会看到这样的函数:
def f(*args, **kwargs):
...
您可以使用任何您想要的参数来调用它:
f(1, 2, 3, a=4, b=5, c=6)
保持顺序:命名参数在位置参数之后。
您可以这样声明一个函数:
f(m1, m2, ..., o1=1, o2=2, ..., *args, **kwargs):
pass
了解以下内容:
- m1、m2、... 强制性:调用时,必须按照位置或名称填写。
- o1, o2, ... 是 可选的:当你调用时,你可以省略这些参数(省略它们意味着不按位置或按名称传递它们),并且它们将保留等号后的值(此类值在函数声明时计算 - 避免使用可变对象作为它们的值)。
- args 和 kwargs 是我之前向您解释的:任何按位置和名称不匹配的参数都会进入这些参数。有了这些特性,你就可以清楚地区分什么是形参,什么是实参。
- 所有这些参数都是可选的。您可以选择不使用强制性的,而只使用可选的。您可以选择不使用
*args
但使用**kwargs
,依此类推。但是尊重声明中的顺序:强制,可选,*args
,**kwargs
。
当你调用方法并传递参数时语义非常不同所以要小心:
f(1) # passes a positional argument. Has nothing to do with the parameter being mandatory.
f(a=1) # passes a named argument. Has nothing to do with the parameter being optional.
f(**i) # UNPACKS the positional arguments. Has nothing to do with the function having a *args parameter, but *args will hold any unpacked -but unmatched- positional argument from i (which is any type of sequence or generator)
f(**d) # UNPACKS its values as named arguments. Has nothing to do with the function having a **kwargs parameter, but **kwargs will hold any unpacked -but unmatched- argument from d (which is a dict having string keys).
当你调用的时候,你可以随意传递它们,这与实际的方法签名无关(即预期的参数),但是 尊重参数的顺序:positional, named, *positionalUnpack, **keywordUnpack,否则你会得到一个很好的 TypeError
.
示例:
def f(a, b=1, *args, **kwargs):
pass
有效调用:
f(1) # a = 1, b = 2, args = (), kwargs = {}
f(*[1]) #a = 1, b = 2, args = (), kwargs = {}
f(*[3, 4]) #a = 3, b = 4, args = (), kwargs = {}
f(**{'a':1, 'b':3}) #a = 1, b=3, args = (), kwargs = {}
f(1, *[2, 3, 4], **{'c': 5}) #a = 1, b=2, args=(3, 4), kwargs = {'c': 5}
再次注意:
- 不要传递相同的参数两次(**解压参数与其他命名参数、位置参数或*解压参数之间会发生冲突)。
如果要将 *args 或 **kwargs 传递给
super
调用,请确保使用解包语法:def my_method(self, a, b, *args, **kwargs): super(MyClass, self).my_method(a+1, b+1, *args, **kwargs)