参考parent的class方法没有parent的class名称

Refer to parent's class method without parent's class name

希望你一切顺利。这个问题实际上是关于摆脱对 base class.

的引用

基本上我想收集 child class 方法在 class 级别而不是实例级别的所有方法,使用 parent class方法。但是,有人告诉我基本 class 名称真的很长。

第一个作品有效,但由于名称太长,真的很烦人。即使在干净的版本中,我每次都必须做 A.eat。

我保证人们不会像 B 那样在任何 child 中定义另一个方法 "eat"。我真的可以去掉基础 class 引用以便我可以使用 @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)

此致,

class IDontWantToDoThisButNameHasToBeThisLong 实际上只是一个对象。在 python 中,大多数 thinga 都是一个对象,因此我们可以将任何东西赋值给一个变量,包括 class.

你可以在这里做的是类似下面的事情

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)

对于您想要做的事情,没有完美的解决方案,但有几种不同的方法可能就足够了。

从最简单的开始,在子 classes:

中使用 class 方法之前,您可以给长 class 一个较短的名称
class IDontWantToDoThisButNameHasToBeThisLong(object):
    ...

A = IDontWantToDoThisButNameHasToBeThisLong

# later code can use A.whatever()

另一种选择是将装饰器从具有长名称的 class 中移出,这样您以后的代码将直接将其作为全局引用,而不是 class 方法。这将需要对其进行稍微重新设计(如果您打算有多个不同的 a 列表,这些列表通过不同的 classes 调用的相同装饰器访问,这可能会破坏事情):

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

这两种方法的混合可能是保留现有的 class 方法定义不变,但为绑定方法创建另一个更易于访问的全局名称:

eat = IDontWantToDoThisButNameHasToBeThisLong.eat

最后一种可能的方法是使用更高级的元classes 编程,或者(如果您使用 Python 3.6)__init_subclass__ 或类似的,以实现目标你不需要使用 class 方法作为装饰器。我不会为此添加代码,因为执行此操作的最佳方法可能取决于您设计的更多细节,而不是您在示例中展示的内容。