我在努力理解这个block of code
class primitive(object):
...
def __get__(self, obj, objtype):
if sys.version_info >= (3,):
def __get__(self, obj, objtype):
return types.MethodType(self, obj)
else:
def __get__(self, obj, objtype):
return types.MethodType(self, obj, objtype)
有人举过这样的例子吗/为什么我需要这个?你知道吗
您发布的代码用作描述符。 这有以下效果:如果一个类有一个描述符的对象,那么一个实例就有一个与类中的对象同名的属性。你知道吗
如果设置该属性,则调用描述符的
__set__(self, instance, value)
命令。你知道吗如果删除它,则调用描述符时使用
__delete__(self, instance)
函数。你知道吗如果您试图接收存储在该属性中的数据,则调用描述符的
__get__(self, instance, owner)
方法。 (owner是包含描述符对象的类)self参数是描述符本身(就像python中的任何其他对象一样),instance参数是包含修改的属性的对象。你知道吗
因此,在这种情况下,接收具有底层
primitive
的属性的数据会导致py2的types.MethodType(self, instance)
或py3的types.MethodType(self, instance, owner)
,其中self
是原语,instance
是检索属性的对象,owner
是持有primitive
对象的类。(如前所述)我希望我能帮上忙
代号lambda
在python中,每当一个类定义
__get__
、__set__
或__delete__
时,就称之为描述符类。这些属性赋予类属性“绑定”行为。这基本上意味着,每当您使用通常的点表示法通过类作为属性访问该对象时,它将根据调用的类型运行这些定义的方法之一。您发布的代码只定义了__get__
,这使它成为非数据描述符。你知道吗这里有另一个被重写的dunder方法开始发挥作用,
__call__
这使您的类成为一个可调用的对象:如您所见,您可以对实例进行任意调用,就像任何其他可调用的(例如函数)一样。我之所以要讨论这个问题,是因为描述符类返回
types.MethodType(self, obj)
或types.MethodType(self, obj, objtype)
,这取决于您使用的python版本。你知道吗MethodType
绑定其第一个参数,该参数必须可调用到其第二个参数,即类实例。本质上,每次访问primitive
描述符对象时,都是在类实例对象上创建绑定方法。你知道吗这里的“descriptor”特性只有在用作类属性时才真正被使用,通过
primitive
docstring读取它提到的类包装函数作为装饰器。你知道吗在下面的几行中,你可以看到它作为一个装饰者在起作用:
但在这里用作描述符类:
在这里,您可以看到类
FloatNode
正在调用所有 两个“ops”列表中的字符串。同样的setattr
调用primitive
是 调用getattr
来检索相同的内置方法 来自类型float
的名称,将其作为初始func
参数传入。现在,无论何时访问这些操作,它们都是绑定方法。你知道吗因此,如果您调用其中一个被设置为
FloatNode
属性的“ops”:您将得到一个绑定方法,它封装了
primitive
所拥有的所有优点(即梯度函数)。你知道吗相关问题 更多 >
编程相关推荐