使用装饰器时覆盖静态变量的值
Override the value of a static variable while using decorator
我创建了一个 class 如下所示:
class Simon:
name = 'Simon'
@classmethod
def says(cls, sentence):
return '%s says: %s' % (cls.name, sentence)
如果我想西蒙说坐下,我可以这样做:
>>> Simon.says('sit down')
'Simon says: sit down'
要用另一个名字替换 Simon,比如 Eva,我可以这样子 class:
class Eva(Simon):
name = 'Eva'
结果:
>>> Eva.says('stand up')
'Eva says: stand up'
现在我想通过创建一个名为 to_past_tense
:
的装饰器将 said 更改为 said
class Eva(Simon):
name = 'Eva'
def to_past_tense(self, func):
def wrapper(*arg, **kw):
present_tense = func(*arg, **kw)
past_tense = present_tense.replace('says', 'said')
return past_tense
return wrapper
@classmethod
def says(cls, *arg, **kw):
return cls.to_past_tense(cls, Simon.says)(*arg, **kw)
如果我这样做:
>>> Eva.says('stand up')
我期待的是:
'Eva said: stand up'
但事实上我得到了这个
'Simon said: stand up'
如何覆盖该值?
还有,如果标题不准确和不清晰,请帮我改进一下,谢谢!
我不完全确定你想在这里实现什么,但我想你需要将 cls.says
传递给方法:
return cls.to_past_tense(cls, cls.says)(*arg, **kw)
您正在使用 Simon.says
,检索绑定 class。
如果您想获取覆盖的 class 方法但将其绑定到当前 class,请使用 super()
proxy object:
@classmethod
def says(cls, *arg, **kw):
return cls.to_past_tense(cls, super().says)(*arg, **kw)
super()
对象会搜索class的MRO,找到Simon
上的says
方法,然后绑定到cls
对象上对你来说,所以 cls.name
值仍然是从 Eva
:
中查找的
>>> class Simon:
... name = 'Simon'
... @classmethod
... def says(cls, sentence):
... return '%s says: %s' % (cls.name, sentence)
...
>>> class Eva(Simon):
... name = 'Eva'
... def to_past_tense(self, func):
... def wrapper(*arg, **kw):
... present_tense = func(*arg, **kw)
... past_tense = present_tense.replace('says', 'said')
... return past_tense
... return wrapper
... @classmethod
... def says(cls, *arg, **kw):
... return cls.to_past_tense(cls, super().says)(*arg, **kw)
...
>>> Eva.says('Hello')
'Eva said: Hello'
我创建了一个 class 如下所示:
class Simon:
name = 'Simon'
@classmethod
def says(cls, sentence):
return '%s says: %s' % (cls.name, sentence)
如果我想西蒙说坐下,我可以这样做:
>>> Simon.says('sit down')
'Simon says: sit down'
要用另一个名字替换 Simon,比如 Eva,我可以这样子 class:
class Eva(Simon):
name = 'Eva'
结果:
>>> Eva.says('stand up')
'Eva says: stand up'
现在我想通过创建一个名为 to_past_tense
:
class Eva(Simon):
name = 'Eva'
def to_past_tense(self, func):
def wrapper(*arg, **kw):
present_tense = func(*arg, **kw)
past_tense = present_tense.replace('says', 'said')
return past_tense
return wrapper
@classmethod
def says(cls, *arg, **kw):
return cls.to_past_tense(cls, Simon.says)(*arg, **kw)
如果我这样做:
>>> Eva.says('stand up')
我期待的是:
'Eva said: stand up'
但事实上我得到了这个
'Simon said: stand up'
如何覆盖该值?
还有,如果标题不准确和不清晰,请帮我改进一下,谢谢!
我不完全确定你想在这里实现什么,但我想你需要将 cls.says
传递给方法:
return cls.to_past_tense(cls, cls.says)(*arg, **kw)
您正在使用 Simon.says
,检索绑定 class。
如果您想获取覆盖的 class 方法但将其绑定到当前 class,请使用 super()
proxy object:
@classmethod
def says(cls, *arg, **kw):
return cls.to_past_tense(cls, super().says)(*arg, **kw)
super()
对象会搜索class的MRO,找到Simon
上的says
方法,然后绑定到cls
对象上对你来说,所以 cls.name
值仍然是从 Eva
:
>>> class Simon:
... name = 'Simon'
... @classmethod
... def says(cls, sentence):
... return '%s says: %s' % (cls.name, sentence)
...
>>> class Eva(Simon):
... name = 'Eva'
... def to_past_tense(self, func):
... def wrapper(*arg, **kw):
... present_tense = func(*arg, **kw)
... past_tense = present_tense.replace('says', 'said')
... return past_tense
... return wrapper
... @classmethod
... def says(cls, *arg, **kw):
... return cls.to_past_tense(cls, super().says)(*arg, **kw)
...
>>> Eva.says('Hello')
'Eva said: Hello'