我有一个对象层次结构,其中几乎所有的方法都是类方法。看起来如下:
class ParentObject(object):
def __init__(self):
pass
@classmethod
def smile_warmly(cls, the_method):
def wrapper(kls, *args, **kwargs):
print "-smile_warmly - "+kls.__name__
the_method(*args, **kwargs)
return wrapper
@classmethod
def greetings(cls):
print "greetings"
class SonObject(ParentObject):
@classmethod
def hello_son(cls):
print "hello son"
@classmethod
def goodbye(cls):
print "goodbye son"
class DaughterObject(ParentObject):
@classmethod
def hello_daughter(cls):
print "hello daughter"
@classmethod
def goodbye(cls):
print "goodbye daughter"
if __name__ == '__main__':
son = SonObject()
son.greetings()
son.hello_son()
son.goodbye()
daughter = DaughterObject()
daughter.greetings()
daughter.hello_daughter()
daughter.goodbye()
给定的代码输出如下:
greetings
hello son
goodbye son
greetings
hello daughter
goodbye daughter
我希望代码输出以下内容:
-smile_warmly - SonObject
greetings
-smile_warmly - SonObject
hello son
-smile_warmly - SonObject
goodbye son
-smile_warmly - DaughterObject
greetings
-smile_warmly - DaughterObject
hello daughter
-smile_warmly - DaughterObject
goodbye daughter
但是我不想在每个方法之前添加行@smile_warmly
(当我在上面的代码中尝试这样做时,我会得到错误消息TypeError: 'classmethod' object is not callable
)。相反,我希望每个方法的修饰都以编程方式在__init__()
方法中进行。
在Python中可以编程地修饰方法吗?
编辑:找到似乎有用的东西--请参阅下面的我的答案。多亏了布伦巴恩。
这个解决方案产生了我想要的输出:
输出为:
decorator所做的只是返回一个新函数。这:
与此相同:
你可以随时做同样的事情,不需要
@
语法,只要用你喜欢的东西替换函数。所以在__init__
或者其他地方,您可以循环遍历所有方法,对于每个方法,用smilewarmly(meth)
替换它。但是,与其在
__init__
中执行,不如在创建类时执行。您可以使用一个元类,或者更简单地使用一个类装饰器:在本例中,我将classmethod装饰放在我的
smileDeco
装饰器中。你也可以把它放在makeSmiley
中,这样makeSmiley
返回smileDeco(classmethod(val))
。(你想用哪种方法来实现它取决于smile decorator与classmethods的关系有多紧密)这意味着你不必在类中使用@classmethod
。当然,在
makeSmiley
的循环中,您可以包括您想要决定(例如,基于方法名)是否用微笑行为包装它的任何逻辑。请注意,如果您真的想在类中手动使用
@classmethod
,那么就必须更加小心,因为通过类__dict__
访问的类方法是不可调用的。因此,您必须特别检查对象是否是classmethod对象,而不是仅仅检查它是否可调用。相关问题 更多 >
编程相关推荐