在子 class 中设置父属性
Setting parent attributes in child class
我突然意识到我可以设置一个只有它的父级才能使用的子级 class 的属性
In [34]: class A:
...: def __init__(self):
...: pass
...:
...: def a(self):
...: print(f'b = {self.b}')
...:
...: class B(A):
...: def __init__(self):
...: super(B, self).__init__()
...: self.b = 1
...:
In [35]: b = B()
...: b.a()
b = 1
这个实现似乎违反直觉,感觉有些不对劲,但我不太确定它是什么。
我认为以下更有意义
In [38]: class A:
...: def __init__(self, b):
...: self.b = b
...:
...: def a(self):
...: print(f'b = {self.b}')
...:
...: class B(A):
...: def __init__(self):
...: super(B, self).__init__(1)
...:
In [39]: b = B()
...: b.a()
b = 1
是否存在前者比后者更推荐实施的用例?
从概念上讲,您正在做两件不同的事情。在第一种情况下,你有类似 abstract class 的东西;换句话说,一个基础 class 不打算单独实例化,因为某些属性的定义是 "missing";据了解,subclasses 将实现这些属性。
更惯用的方法是使用 abc
模块将 A
标记为 抽象基础 class ,例如:
from abc import ABCMeta, abstractmethod
class A(metaclass=ABCMeta):
@property
@abstractmethod
def x(self):
pass
def print_me(self):
print(f'x = {self.x}')
class B(A):
@property
def x(self):
return 1
A().print_me()
输出将是:
TypeError: Can't instantiate abstract class A with abstract methods x
另一方面,这有效:
B().print_me() # prints x = 1
通过这样做,您清楚地表明子class 必须覆盖x
属性,否则print_me
功能将不起作用。
转到第二种情况,你有一个具体的基础 class 和 subclass,subclass 的作用类似于对实例性质的约束,可以是创建。在这种情况下, A
的独立实例是完全有效的;只是 B
的实例提供了额外的保证,即特定属性将始终为某个值(或者,如果您希望 class 可变,则至少初始化为某个值).
我突然意识到我可以设置一个只有它的父级才能使用的子级 class 的属性
In [34]: class A:
...: def __init__(self):
...: pass
...:
...: def a(self):
...: print(f'b = {self.b}')
...:
...: class B(A):
...: def __init__(self):
...: super(B, self).__init__()
...: self.b = 1
...:
In [35]: b = B()
...: b.a()
b = 1
这个实现似乎违反直觉,感觉有些不对劲,但我不太确定它是什么。
我认为以下更有意义
In [38]: class A:
...: def __init__(self, b):
...: self.b = b
...:
...: def a(self):
...: print(f'b = {self.b}')
...:
...: class B(A):
...: def __init__(self):
...: super(B, self).__init__(1)
...:
In [39]: b = B()
...: b.a()
b = 1
是否存在前者比后者更推荐实施的用例?
从概念上讲,您正在做两件不同的事情。在第一种情况下,你有类似 abstract class 的东西;换句话说,一个基础 class 不打算单独实例化,因为某些属性的定义是 "missing";据了解,subclasses 将实现这些属性。
更惯用的方法是使用 abc
模块将 A
标记为 抽象基础 class ,例如:
from abc import ABCMeta, abstractmethod
class A(metaclass=ABCMeta):
@property
@abstractmethod
def x(self):
pass
def print_me(self):
print(f'x = {self.x}')
class B(A):
@property
def x(self):
return 1
A().print_me()
输出将是:
TypeError: Can't instantiate abstract class A with abstract methods x
另一方面,这有效:
B().print_me() # prints x = 1
通过这样做,您清楚地表明子class 必须覆盖x
属性,否则print_me
功能将不起作用。
转到第二种情况,你有一个具体的基础 class 和 subclass,subclass 的作用类似于对实例性质的约束,可以是创建。在这种情况下, A
的独立实例是完全有效的;只是 B
的实例提供了额外的保证,即特定属性将始终为某个值(或者,如果您希望 class 可变,则至少初始化为某个值).