我学习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?
答案 0 :(得分:4)
Python函数支持关键字参数:
def add(a, b):
return a + b
add(a=1, b=2)
这发生在这里。
Configurator(settings=settings)
第一个settings
是__init__
Configurator
中参数的名称。第二个是当前名称空间中对象的名称。
答案 1 :(得分:2)
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
因此,当您传递一个命名参数时,请确保不要两次传递相同的参数(即也按位置),并检查参数名称是否存在(另外:如果记录参数可以/应该按名称传递,尊重继承/覆盖的名称。
另外 Python支持传递*arguments
和**keyword_arguments
。这些是您可以以可变方式处理的其他参数,因为许多语言都支持它们。
*args
(名称无关紧要 - 它必须有一个星号作为位置可变参数;它是一个元组)保存剩余的不匹配的位置参数(而不是获取TypeError为位置参数是意外的,这样的参数作为元素进入*args
。
**kwargs
(名称无关紧要 - 它必须有两个星号作为命名/关键字可变参数;它是一个字典)保存剩余的不匹配的命名参数(而不是获取命名参数的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
了解以下内容:
*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).
当您拨打电话时,您可以根据需要传递它们,这与实际方法签名无关(即预期参数),但尊重订单与参数一样:位置,命名,* 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)
答案 2 :(得分:1)
这意味着您将参数设置传递给配置器,其中包含一个名为设置的变量
这里有一个例子,你有一个功能:
def function_test(a=None, b=None, c=None):
pass
你可以这样称呼它:
c = "something"
function_test(c=c)
表示您在函数 function_test
中传递了您作为参数 c 的参数创建的变量 c答案 3 :(得分:1)
它说它在settings
中传递了本地名称settings
作为名为Configurator
的参数。
对于x=y
形式的函数或构造函数调用,x
是函数/构造函数端本地使用的参数名称,而y
是调用者端的名称。在这种情况下,它们恰好是同一个名字。