我是一个比较新的Python学习者。所以,在使用不同的编码技术时,我发现:
from inspect import Parameter, Signature
def make_signature(names):
return Signature(Parameter(name, Parameter.POSITIONAL_OR_KEYWORD) for name in names)
class Structure:
list_fields = []
def __init__(self, *args):
for name, val in zip(self.list_fields, args):
setattr(self, name, val)
class Stock(Structure):
__signature__ = make_signature(['name', 'shares', 'price'])
#list_fields = ['name', 'shares', 'price']
class Point(Structure):
list_fields = ['x', 'y']
obj2=Point(20,40)
obj1=Stock('googl', 100, 8000)
print(obj1.name)
我了解Structure
类及其与继承Structure
类的Point
类的集成,因此它是__init__
方法。但是当我创建Point
类的对象时,它不支持位置参数,但是Stock
类对象确实支持这个特性。在
make_signature
方法中,Parameter
函数的用途是什么,make_signature
方法在做什么?在我试着读了一些关于Signature
的文档,但这些例子不是这种类型的,对我来说太沉重了,因为我一直在回溯这些代码文档,我也找不到任何关于Python中元编程的好的解释性文档。在
这两个类都只接受由^{中的
*args
指定的位置参数:区别在于,
Stock
实际上并没有设置任何参数,因为,由于您注释掉了list_fields
,Structure.__init__
将使用空的Structure.list_fields
。这就是为什么尝试在Stock
实例上访问name
会引发一个AttributeError
。在在这两种情况下,};
^{pr2}$list_fields
限制了可以设置的参数。对于前一个片段中的Point
实例,x
将等于pos_arg1
,y
将等于{pos_arg3
本质上是被抛出的。这是由于zip
构建元组,直到其中一个iterable用尽:印刷品:
即使列表为空,也不会提供循环。这是初始化
Stock
时发生的情况,Structure.list_fields = []
被使用:不打印任何内容,因此不会调用
setattr
。在当你想支持你的类(或者在一般情况下是可调用的)的时候,你可以在你的类中添加一个
__signature__
属性(就像Stock
)并通过类似inspect.signature
的工具来获取它,例如:Signature尝试查看对象是否具有
object.__signature__
,如果是,则在调用时构造签名的表示形式。在此外,您可以
bind
一个签名给self并让它支持POSITIONAL_OR_KEYWORD
参数。在一般来说,这只会在极少数情况下作为要求出现。简而言之:你会知道你是否需要它。在
这个具体的例子与此无关。你可以用元编程来增强它,正如你在我将要链接的演示中看到的那样。在
这要求太宽泛了。但是您的例子来自davidbeazly的元编程演示here's the presentation。在
Stock
和Point
都使用Structure.__init__
,它将用list_fields
中定义的属性填充实例字典。在当创建类时,
__signature__ = make_signature([...])
正在执行,Python在遇到它时执行class
的主体。make_signature
将被调用并创建一个Signature
对象,并对__signature__
进行赋值。在相关问题 更多 >
编程相关推荐