Существует ключевая проблема с этим утверждением:
Я хотел бы определить функцию с тем же именем, как своего родителя, который возвращает значение, которое родитель может получить
Могу ли я спросить, почему это необходимо?
f
в классе «Дети» совершенно отличается от f
в классе родительских классов, поэтому их называть одним и тем же очень сложно, даже если вы его заработаете.
Позволяет сказать, что я написал класс ребенка, используя ваш Parent
:
class Child(Parent):
def f(self):
return 2
Я ожидал бы Child().f()
вернуться 2, но если вы добавляете скрытую логику за кулисами, который добавляет arg ** 3
тогда я вместо того, чтобы получить 8 и быть полностью запутанным и проклинать вашу библиотеку за добавление очень неинтуитивных правил.
Вместо почему не одну функцию, которая используется и определить дополнительные вспомогательные функции логики в подклассах:
class Parent:
def f(self, *v_args):
arg = self.helper_f(*v_args)
print("Received {}.".format(arg))
return arg ** 3
def helper_f(self,*args):
"really should be an abstract method, must be implemented in a subclass"
raise NotImplementedError("Must override in a subclass!")
class Child(Parent):
def helper_f(self, c, b, a):
print(a, b, c)
return a
# Prints "Received 2.". Sets value to 8.
value = Child().f(0, 1, 2)
Конечно, да, технически может автоматизировать этот мета класса. Но опять же, это было бы совершенно запутанным к любому, используя свой Parent
класс
class Child_Method_Redirector(type):
def __new__(meta, name, bases, cls_dict):
if bases is not():
if "f" in cls_dict:
cls_dict["_auto_renamed_helper_f"] = cls_dict["f"]
del cls_dict["f"]
return type.__new__(meta,name,bases,cls_dict)
class Parent(metaclass=Child_Method_Redirector):
def f(self, *v_args):
arg = self._auto_renamed_helper_f(*v_args)
print("Received {}.".format(arg))
return arg ** 3
class Child(Parent):
def f(self):
return 2
# now it does Print "Received 2." and Sets value to 8.
value = Child().f()
Но Пожалуйста, не делайте этого, он идет против the zen
Явное лучше, чем неявное.
Должен быть один - и желательно только один - простой способ сделать это.
Если реализация трудно объяснить, это плохая идея.
Печать '2 1 0' на Python 2.7 и 3.4 – csl
Если определить метод в подклассе с тем же именем, то по определению переопределить родительский метод. Я почти уверен, что вы хотите сделать, это невозможно и будет плохой идеей.Я предлагаю, чтобы у вас есть 'f' в родительском вызове некоторый абстрактный метод' g', за который ребенок отвечает за переопределение. –
Обратите внимание, что это будет просто 'return super(). F (a)'. – jonrsharpe