引用不带父类的父类方法

2024-10-04 01:34:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望你做得很好。这个问题实际上是关于去掉对基类的引用。你知道吗

基本上,我希望使用父类方法在类级别(而不是实例级别)收集子类方法的所有方法。但是,我被告知基类名称非常长。你知道吗

第一件作品的作品,但真的很烦人,因为长的名字。即使是干净的版本,我每次都要吃。你知道吗

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

真诚地


Tags: 方法版本objectdef级别基类子类作品
2条回答

IDontWantToDoThisButNameHasToBeThisLong实际上只是一个对象。在python中,大多数thingsa都是一个对象,因此我们可以将几乎任何东西赋给一个变量,包括一个类。你知道吗

你可以在这里做如下的事情

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)

对于您想要做的事情,没有完美的解决方案,但是有一些不同的方法可能已经足够好了。你知道吗

从最简单的方法开始,在子类中使用class方法之前,可以为长类指定一个较短的名称:

class IDontWantToDoThisButNameHasToBeThisLong(object):
    ...

A = IDontWantToDoThisButNameHasToBeThisLong

# later code can use A.whatever()

另一种选择是将decorator从具有长名称的类中移出,这样以后的代码将直接将其引用为全局方法,而不是类方法。这需要稍微重新设计一下(如果您希望有多个不同的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

最后一种可能的方法是使用更高级的元类编程,或者(如果您使用的是python3.6)__init_subclass__或类似的方法,以实现您心目中的目标,而不需要使用类方法作为装饰器。我不打算包含这方面的代码,因为实现这一点的最佳方法可能取决于设计的更多细节,而不是示例中显示的细节。你知道吗

相关问题 更多 >