Декорирование метода родительского класса

StackOverflow https://stackoverflow.com/questions/66636

  •  09-06-2019
  •  | 
  •  

Вопрос

Я хотел бы создать дочерний класс, который имеет метод родительского класса, где этот метод является «методом класса» в дочернем классе, но нет в родительском классе.

По сути, я пытаюсь добиться следующего:

class foo(Object):
    def meth1(self, val):
        self.value = val

class bar(foo):
    meth1 = classmethod(foo.meth1)
Это было полезно?

Решение

Я также не совсем уверен, какое именно поведение вы хотите, но предполагая, что вы хотите, чтобы bar.meth1(42) был эквивалентен foo.meth1, являющемуся методом класса bar (где «self» является классом), тогда вы можете добиться этого с помощью:

def convert_to_classmethod(method):
    return classmethod(method.im_func)

class bar(foo):
    meth1 = convert_to_classmethod(foo.meth1)

Проблема с classmethod(foo.meth1) заключается в том, что foo.meth1 уже преобразован в метод со специальным значением для первого параметра.Вам нужно отменить это и посмотреть на базовый объект функции, по-новому интерпретируя значение слова «self».

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

Другие советы

Что вы пытаетесь достичь?Если бы я увидел такую ​​конструкцию в живом коде Python, я бы подумал о том, чтобы превзойти оригинального программиста.

Вопрос в такой постановке кажется мне довольно странным:Я не понимаю, почему кто-то хочет это сделать.Возможно, вы неправильно понимаете, что такое «метод класса» в Python (он немного отличается, скажем, от статического метода в Java).

Обычный метод — это более или менее просто функция, которая принимает в качестве первого аргумента (обычно называемого «self») экземпляр класса и вызывается как «.».

Classmethod-это более или менее просто функция, которая принимает свой первый аргумент (часто называемый «CLS»), класс, и которая может быть вызвана как «». Или как ".".

Учитывая это и ваш код, показанный выше, что вы ожидаете, если кто-то создаст экземпляр bar и вызовет для него meth1?

bar1 = bar()
bar1.meth1("xyz")

Когда вызывается код meth1, ему передаются два аргумента «self» и «val».Я предполагаю, что вы ожидаете, что «xyz» будет передано вместо «val», но что, по вашему мнению, будет передано вместо «self»?Должен ли это быть экземпляр bar1 (в данном случае переопределение не требовалось)?Или это должна быть панель классов (что тогда будет делать этот код)?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top