我有一个带有类属性的类Klass
。我有它的一个子类SubKlass
,其中我想要一个类属性my_list
,它是父类中相同属性的修改版本:
class Klass():
my_list = [1, 2, 3]
class SubKlass(Klass):
my_list = Klass.my_list + [4, 5] # this works, but i must specify parent class explicitly
#my_list = super().my_list + [4, 5] # SystemError: super(): __class__ cell not found
#my_list = my_list + [4, 5] # NameError: name 'my_list' is not defined
print(Klass.my_list)
print(SubKlass.my_list)
那么,有没有一种方法可以访问父类属性而不指定其名称?
更新:
python问题跟踪程序上有一个错误:http://bugs.python.org/issue11339。希望在某个时刻是solved。
你不能
类定义在Python中的工作方式如下。
解释器看到一个
class
语句,后面跟着一段代码。它创建一个新的名称空间并在名称空间中执行该代码。
它使用生成的命名空间、类名、基类和元类(如果适用)调用
type
内置。它将结果赋给类的名称。
在类定义中运行代码时,您不知道基类是什么,因此无法获取它们的属性。
您可以在定义类之后立即修改它。
编辑:这里有一个小的类装饰器,可以用来更新属性。这个想法是你给它一个名字和一个函数。它会查看类的所有基类,并使用该名称获取它们的属性。然后它使用从基类继承的值列表和在子类中定义的值调用函数。此调用的结果已绑定到该名称。
代码可能更有意义:
其思想是将
x
定义为(2,)
中的Bar
。然后,decorator将遍历Bar
的子类,找到它们的所有x
,并与它们一起调用update_x
。所以它会叫它通过连接它们来组合它们,然后再次将其绑定回
x
。这有道理吗?正如@katrielex所回答的,
my_list
在创建类之前默认不在命名空间中。但是,在Python 3中,如果您想深入研究元类,可以手动将my_list
添加到命名空间中:注意,这个示例可能还不能很好地处理菱形继承结构。
新的
__prepare__
属性在PEP 3115中定义。您可以使用元类或类装饰器。下面是如何在Python2.x中使用元类:
在Python 3中,您可以使用较新的语法声明元类:
相关问题 更多 >
编程相关推荐