Как наследовать, когда экземпляр создан с помощью рекурсивного @staticmethod родителя в python - PullRequest
0 голосов
/ 21 февраля 2020
class P:
  def __init__(self):
    pass
  @staticmethod
  def from_static():
    return P()
  def parent():
    print("parent")


class C(P):
  def child():
    print("child")


c = C.from_static()

dir(c)

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'from_static', 'parent']

Нет дочернего () метода!

Метод stati c перенаправляет свой собственный метод __init__, который находится в классе родителя. В результате экземпляр метода 'c' не может иметь метод child ().

Как мы можем определить класс 'c' с помощью дополнительного метода child (), если мы хотим создать с помощью метод stati c в родительском? Мне не нужно трогать класс 'p'.

def f(x):
  return x*2, x**2

class P:
  def __init__(self, a, b):
    self.a = a
    self.b = b
  @staticmethod
  def from_static(x):
    a, b = f(x)
    return P(a, b)
  def parent():
    print("parent")


class C(P):
  def child():
    print("child")


c = C.from_static()

dir(c)

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'from_static', 'parent']

Второй код - это заданный код, который немного больше.

1 Ответ

0 голосов
/ 21 февраля 2020

Когда вы вызываете C.from_static, вы получаете тот же результат, как если бы вы вызывали P.from_static, экземпляр класса P. Это потому, что метод предназначен для того, чтобы всегда возвращать этот результат.

Это недостаток использования методов stati c. Они всегда делают одно и то же, независимо от того, в каком классе вы их называете. Если вы хотите, чтобы метод вел себя по-другому, если он вызывается в подклассе, вы, вероятно, не хотите staticmethod, а вместо этого classmethod.

Когда вы вызываете classmethod, метод будет получить класс, для которого он был вызван, в качестве первого аргумента (традиционно называемый cls, хотя это не обязательно). Затем вы можете вызывать класс с помощью этого аргумента, а не называть его сами.

Попробуйте:

class P:
  @classmethod                  # change decorator
  def from_static(cls):         # add cls argument here
    return cls()                # call the class that was passed in, not always P
...