【问题标题】:Possible to create a classmethod as a non-decorator?可以将类方法创建为非装饰器吗?
【发布时间】:2020-02-10 15:08:33
【问题描述】:

假设我有以下课程:

class Item:
    def __init__(self, string=''):
        self.string = string
    @classmethod
    def from_string(cls, string):
        return cls(string=string)

上述案例中的classmethod不是必需的,因为我可以很容易地调用Item(string='asdf')而不是Item.from_string(string='asdf'),但我只是以它为例。

是否可以在类本身之外附加任意classmethod?例如,类似:

def from_string(cls, string):
    return cls(string=string)

classmethod(from_string(Item, "asdf"))

或者,写成这样:

class Item:
    def __init__(self, string=''):
        self.string = string
    from_string = classmethod(f)
    def f(string):
        return Item(string)

基本上,我试图更多地了解装饰器,以及如何在正常上下文之外使用它们(看看它们在幕后做了什么)。

【问题讨论】:

  • 你想让classmethodclassmethod(from_string(Item, "asdf")) 中做什么?我看不出它会扮演什么角色。如果你想拨打from_string,则完全不需要涉及classmethodfrom_string(Item, "asdf") 工作正常。
  • 只需将您的“classmethod(...)”分配给 e。 G。 “Item.from_string”。这里真正的魔力是descriptor protocol

标签: python python-3.x decorator class-method


【解决方案1】:
@classmethod
def from_string(cls, string):
    return cls(string=string)

等价于

def from_string(cls, string):
    return cls(string=string)
from_string = classmethod(from_string)

class Item:
    def __init__(self, string=''):
        self.string = string
    from_string = classmethod(f)
    def f(string):
        return Item(string)

应该改成

class Item:
    def __init__(self, string=''):
        self.string = string
    def f(string):
        return Item(string)
    from_string = classmethod(f)

【讨论】:

  • 这种等价性在某些情况下(主要是奇怪的元类)并不完全成立,因为装饰器版本只对from_string 执行一次赋值,而非装饰器版本执行两个。在大多数情况下,这些版本可能被认为是等效的。
猜你喜欢
  • 2011-05-18
  • 2011-04-11
  • 1970-01-01
  • 2015-06-06
  • 2019-08-31
  • 2011-01-22
  • 2017-02-04
  • 2012-09-03
相关资源
最近更新 更多