2017-02-21 20 views
0

Надеюсь, вы отлично справляетесь. Эти вопросы действительно касаются избавления от ссылки на базовый класс.Обратитесь к методу класса родителя без имени класса родителя

В основном я хочу собрать все методы методов дочернего класса на уровне класса вместо уровня экземпляра, используя метод родительского класса. Однако мне сказали, что имя базового класса действительно длинное.

Первая часть работает, но очень раздражает из-за длинного имени. Даже в чистой версии я должен каждый раз делать A.eat.

Я обещаю, что люди не будут определять другой метод «есть» в любом ребенке типа 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 перед тем, как вы должны иметь в виду, не используя метод класса в качестве декоратора. Я не собираюсь включать код для этого, так как лучший способ сделать это, вероятно, зависит от более подробной информации о вашем дизайне, чем того, что вы показали в своем примере.

 Смежные вопросы

  • Нет связанных вопросов^_^