在抽象 类 的情况下实例化的最佳方式是什么?
What is the best way for instantiation in the case of abstract classes?
据我目前的理解(注意告诉我我的话定义的正确性):我们应该在抽象中声明我们的抽象方法 class 并将这些方法的实现引导到subclass 或派生 class.
现在我有1个问题:
- 在基础class(抽象class)中有实例化有用或常见吗?
或者,如果不是:
我们应该在派生的 class(子 class)或两者中都有我们的 实例化 吗?
哪个更好做,或者说 pythonic 更好?
或者您可能会说没关系...如果是这种情况,请通知我原因。
例如,这个:
from abc import abstractmethod, ABC
class Athlete(ABC):
def __init__(self, name: str, mass: int, height: int, nationality: str):
self.name = name
self.mass = mass
self.height = height
self.nationality = nationality
@abstractmethod
def run(self):
pass
def play(self):
pass
def exercise(self):
pass
def sleep(self):
pass
class SoccerPlayer(Athlete):
def run(self):
print(f"{self.name} is running")
def play(self):
print(f"{self.name} with {self.height} is running to save his {self.nationality} nation.")
def exercise(self):
print(f"{self.name} is exercising to fit his {self.mass}")
def sleep(self):
print(f"{self.name} is sleeping 8 h a day to increase his {self.height}m height.")
player = SoccerPlayer('ali', 200, 180, 'american')
player.run()
始终对派生的 class 进行实例化。
因为虽然如果你在基class中进行实例化,你将继承派生class中的那些属性和方法,但也要考虑到这一点,你可能想要覆盖属性您已在基础 class(abstract class) 中实例化。那时你需要快速修改你的抽象属性class,这不是一个好主意。
所以在子 class 而不是抽象 class 中实例化你的属性。
对于测试,实例化一个抽象基class可能会很方便。这也很简单。 不要在生产代码中这样做。
你需要做的就是清空Athlete.__abstractmethods__
>>> Athlete("bob", 100, 200, "american")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Athlete with abstract methods run
>>> Athlete.__abstractmethods__
frozenset({'run'})
>>> Athlete.__abstractmethods__ = frozenset()
>>> Athlete("bob", 100, 200, "american")
<__main__.Athlete object at 0x10c9c0410>
据我目前的理解(注意告诉我我的话定义的正确性):我们应该在抽象中声明我们的抽象方法 class 并将这些方法的实现引导到subclass 或派生 class.
现在我有1个问题:
- 在基础class(抽象class)中有实例化有用或常见吗?
或者,如果不是:
我们应该在派生的 class(子 class)或两者中都有我们的 实例化 吗?
哪个更好做,或者说 pythonic 更好?
或者您可能会说没关系...如果是这种情况,请通知我原因。
例如,这个:
from abc import abstractmethod, ABC
class Athlete(ABC):
def __init__(self, name: str, mass: int, height: int, nationality: str):
self.name = name
self.mass = mass
self.height = height
self.nationality = nationality
@abstractmethod
def run(self):
pass
def play(self):
pass
def exercise(self):
pass
def sleep(self):
pass
class SoccerPlayer(Athlete):
def run(self):
print(f"{self.name} is running")
def play(self):
print(f"{self.name} with {self.height} is running to save his {self.nationality} nation.")
def exercise(self):
print(f"{self.name} is exercising to fit his {self.mass}")
def sleep(self):
print(f"{self.name} is sleeping 8 h a day to increase his {self.height}m height.")
player = SoccerPlayer('ali', 200, 180, 'american')
player.run()
始终对派生的 class 进行实例化。
因为虽然如果你在基class中进行实例化,你将继承派生class中的那些属性和方法,但也要考虑到这一点,你可能想要覆盖属性您已在基础 class(abstract class) 中实例化。那时你需要快速修改你的抽象属性class,这不是一个好主意。
所以在子 class 而不是抽象 class 中实例化你的属性。
对于测试,实例化一个抽象基class可能会很方便。这也很简单。 不要在生产代码中这样做。
你需要做的就是清空Athlete.__abstractmethods__
>>> Athlete("bob", 100, 200, "american")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Athlete with abstract methods run
>>> Athlete.__abstractmethods__
frozenset({'run'})
>>> Athlete.__abstractmethods__ = frozenset()
>>> Athlete("bob", 100, 200, "american")
<__main__.Athlete object at 0x10c9c0410>