2017-02-21 85 views
0

我希望你做得很好。这个问题实际上是摆脱了对基类的引用。参考父母的班级方法,不用父母的班级名称

基本上我想要在类级别而不是实例级别使用父级方法来收集子级类方法的所有方法。但是,我被告知基类名称很长。

第一件作品,但由于长名称真的很烦人。即使在干净的版本中,我也必须每次都做。

我保证人们不会在B中的任何一个孩子中定义另一种方法“吃”。我真的可以摆脱基类引用,以便我可以使用@eat吗?

class IDontWantToDoThisButNameHasToBeThisLong(object): 

    a = [] 

    @classmethod 
    def eat(cls, func): 
    cls.a.append(func) 


class B(IDontWantToDoThisButNameHasToBeThisLong): 

    @IDontWantToDoThisButNameHasToBeThisLong.eat 
    def apple(self, x): 
    print x 

    IDontWantToDoThisButNameHasToBeThisLong.eat(lambda x: x+1) 

x = B() 

IDontWantToDoThisButNameHasToBeThisLong.a[0](x, 1) 

print IDontWantToDoThisButNameHasToBeThisLong.a[1](1) 

干净的版本:

class A(object): 

    a = [] 

    @classmethod 
    def eat(cls, func): 
    cls.a.append(func) 


class B(A): 

    @A.eat 
    def apple(self, x): 
    print x 

    A.eat(lambda x: x+1) 

x = B() 

A.a[0](x, 1) 
print A.a[1](1) 

真诚,

回答

0

IDontWantToDoThisButNameHasToBeThisLong实际上只是一个对象。在python中,大多数事物都是一个对象,所以我们可以将任何东西都分配给一个变量,包括一个类。

,你可以在这里做的是一样的东西下面

class IDontWantToDoThisButNameHasToBeThisLong(object): 

    a = [] 

    @classmethod 
    def eat(cls, func): 
     cls.a.append(func) 

A = IDontWantToDoThisButNameHasToBeThisLong 


class B(A): 

    @A.eat 
    def apple(self, x): 
     print x 

    A.eat(lambda x: x+1) 

x = B() 

IDontWantToDoThisButNameHasToBeThisLong.a[0](x, 1)   
A.a[0](x, 1) 

print IDontWantToDoThisButNameHasToBeThisLong.a[1](1) 
0

有你想做的事没有完美的解决方案,但也有可能是不够好几个不同的方法。

首先从最简单的,你可以给你的长类较短的名称在子类中使用类方法之前:

class IDontWantToDoThisButNameHasToBeThisLong(object): 
    ... 

A = IDontWantToDoThisButNameHasToBeThisLong 

# later code can use A.whatever() 

另一种选择是与长期移动装饰出类的名称,以便后面的代码将其直接引用为全局,而不是类方法。这就要求它稍微重新设计(这可能会打破东西,如果你曾经打算让那里是通过通过不同类别的所谓同一装饰访问多个不同的a列表):

class IDontWantToDoThisButNameHasToBeThisLong(object): 
    a = [] 

def eat(func): 
    IDontWantToDoThisButNameHasToBeThisLong.a.append(func) # only need to use the name once 
    return func # I suspect you want this too (a decorator should return a callable) 

# later code can use @eat as a decorator, without referring to the long class name 

这两种的混合方法可能会离开现有的类方法的定义不变,但为绑定的方法那是更容易获得创建另一个全局名称:

eat = IDontWantToDoThisButNameHasToBeThisLong.eat 

最后一个可能的方法是使用与元类票友编程,或者(如果你正在使用Python 3.6)__init_subclass__或类似的,以achi无需使用类方法作为装饰器,即可达到目标。我不会为此包含代码,因为实现此目的的最佳方式可能取决于您的设计的更多细节,而不是您在示例中显示的内容。