2017-07-26 75 views
0

我目前正在学习Python,并且编写了这段代码来探讨装饰器的机制。Python:装饰对象列表

假设我有一个对象列表和一个函数,我想用它们来装饰他们的一个方法,但我不希望装饰是永久的。

这是为了实现该结果的一种方法:

class Human: 
    def __init__(self, name): 
     self.name = name 

class Man(Human): 
    def hello(self): 
     print("Hello, my name is " + self.name) 

    def __call__(self): 
     self.hello() 

class Woman(Human): 
    def hello(self): 
     print("Hello, my name is " + self.name) 

    def __call__(self): 
     self.hello() 

def deco(func): 
    def wrap(): 
     print("-*-*-*-*-*-*-*-*-*-*-*-*-") 
     func() 
     print("*-*-*-*-*-*-*-*-*-*-*-*-*") 
    return wrap 

H = Man("Harry") 
S = Woman("Sally") 

print("\n") 

H.hello() 
S.hello() 

print("\n\nDecoration:\n") 

people = [H, S] 

for f in list(map(deco, people)): 
    f() 

print("\n") 

这是输出:

Hello, my name is Harry 
Hello, my name is Sally 


Decoration: 

-*-*-*-*-*-*-*-*-*-*-*-*- 
Hello, my name is Harry 
*-*-*-*-*-*-*-*-*-*-*-*-* 
-*-*-*-*-*-*-*-*-*-*-*-*- 
Hello, my name is Sally 
*-*-*-*-*-*-*-*-*-*-*-*-* 

这是所需的输出。

另一种方式来获得它可能是去除呼叫定义在类和使用:

functions = [H.hello, S.hello] 

for f in list(map(deco, functions)): 
    f() 

我愿意,因为我明确地传递,我想成为功能装饰为deco()装饰者。

我不太满意,但因为我在寻找一个这样的事

people = [H, S] 

for i in range(len(people)): 
    decoratedHello = deco(people[i].hello) 
    decoratedHello() 

但这个看起来更像是一个C++的思想作风,我正在寻找一种方式来实现这在一个更Python的风格。任何人都知道如何去做?

感谢

+0

我不会称这个装饰,因为你是在实例的基础上做的,这仅仅是一个功能性的封闭,并且在很大程度上是不必要的,因为你可以直接调用该函数。为什么不在类上而不是实例上创建装饰方法? – AChampion

+0

“为什么不在实例上创建装饰方法?”没有理由。这不是一个工作项目,我只是在学习Python并探索它提供的机会:) –

回答

0

你可能想是这样的

for f in (deco(p.hello) for p in people): 
    f() 

或者这

for p in people: 
    decorated = dec(p.hello) 
    decorated() 

但恕我直言,最Python的一个是:#like你的第一次尝试...

for f in map(deco, people): 
    f() 
+0

我真的很喜欢你的第一个解决方案。非常感谢。 –