2024-06-07 17:17:10 发布
网友
以下代码段将导致AttributeError: 'classmethod' object has no attribute 'val'。你知道为什么和如何解决这个问题吗?在
AttributeError: 'classmethod' object has no attribute 'val'
class App(object): @classmethod def cfn(kls, *args): print kls, args cfn.val = 10
实际上,可以向类方法添加自定义属性。在
NB仅在python3.4上测试过
TL;DR
class classmethod_with_custom_attribute(object): def __init__(self, val): self.val = val def __call__(self, func): def wrapped_func(*args, **kwargs): return func(*args, **kwargs) wrapped_func.val = self.val wrapped_func = classmethod(wrapped_func) return wrapped_func class App(object): @classmethod_with_custom_attribute(val=10) def cfn(cls, *args): print(cls, args)
说明
首先,您必须了解decorator是如何工作的,因为classmethod是一个decorator。在
写作
实际上和写作是一样的
def cfn(cls, *args): print(cls, *args) cfn = classmethod(cfn)
现在,如果您尝试向方法添加属性,请不要将其编写为
@classmethod def cfn(cls, *args): print(cls, *args) cfn.val = 10
因为它相当于
def cfn(cls, *args): print(cls, *args) cfn = classmethod(cfn) cfn.val = 10
因此,您将属性添加到decorator返回的方法,而不是实际的方法。简单的解决方案是将属性添加到方法中,然后在该属性之后对其进行装饰:
def cfn(cls, *args): print(cls, *args) cfn.val = 10 cfn = classmethod(cfn)
通过这种方式,可以装饰已经附加了属性的方法,而且显然decorator返回了相同的方法对象,这样就不会丢失属性。 我们都同意这种语法不是很好也不好读。保留decorator语法更好。您可以将所有逻辑放入自定义装饰器中,如下所示:
class classmethod_with_custom_attribute(object): def __init__(self, val): self.val = val def __call__(self, func): def wrapped_func(*args, **kwargs): return func(*args, **kwargs) wrapped_func.val = self.val wrapped_func = classmethod(wrapped_func) return wrapped_func
这里我们做同样的事情,注意在调用类方法decorator之前,分配了自定义属性的部分。现在我们可以像这样使用装饰器:
@classmethod_with_custom_attribute(val=10) def cfn(cls, *args): print(cls, args)
现在你可以打电话了
App.cfn.val
它会像预期的那样工作
类方法根本不支持向它们添加任意属性。最好的办法是将要放入类方法属性中的数据放到其他地方。在
实际上,可以向类方法添加自定义属性。在
NB仅在python3.4上测试过
TL;DR
说明
首先,您必须了解decorator是如何工作的,因为classmethod是一个decorator。在
写作
^{pr2}$实际上和写作是一样的
现在,如果您尝试向方法添加属性,请不要将其编写为
因为它相当于
因此,您将属性添加到decorator返回的方法,而不是实际的方法。简单的解决方案是将属性添加到方法中,然后在该属性之后对其进行装饰:
通过这种方式,可以装饰已经附加了属性的方法,而且显然decorator返回了相同的方法对象,这样就不会丢失属性。 我们都同意这种语法不是很好也不好读。保留decorator语法更好。您可以将所有逻辑放入自定义装饰器中,如下所示:
这里我们做同样的事情,注意在调用类方法decorator之前,分配了自定义属性的部分。现在我们可以像这样使用装饰器:
现在你可以打电话了
它会像预期的那样工作
类方法根本不支持向它们添加任意属性。最好的办法是将要放入类方法属性中的数据放到其他地方。在
相关问题 更多 >
编程相关推荐