[英]What is the proper way to make class data inheritable in python?
我是Python的新手,来自Perl宇宙。
我正在尝试确定关于存储和访问类数据的最佳实践,以便它可以继承并可能由子类扩展。 阅读Python 2.7文档(我真的坚持使用2.6),潜入Python和过去的问题,这个问题的答案并不清楚。
在python伪代码中有点像......
class baseClass:
'DataMap' = {
'key1': 'val1',
'key2': 'val2',
'key3': 'val2',
}
class subClass1(baseClass): # has access to DataMap
def myfunc:
...
if DataMap[x] == 'val2':
print 'foo' # if x equals 'key2' according to the data map
y = DataMap['key4'] # error!
...
class subClass2(baseClass): # appends values to base DataMap
DataMap['key4'] = 'val4'
def myfunc:
...
if DataMap[x] == 'val4':
print 'foo' # if x equals 'key4' according to the data map
elif DataMap[x] == 'val2':
print 'bar' # if x equals 'key2' according to the data map
...
我上面写的有些Perl意识到直接类数据访问很常见,并且由于调用方法的开销而大多受到鼓励。 我觉得这种方法并不是非常pythonic,但我想要一个健全检查确定。
DataMap虽然在编译后是不可变的,但它应该驻留在一个类函数中,当继承baseClass时,subClass1将通过类方法获取该数据,而subClass2可以覆盖相同的方法来附加/合并其数据映射与基数?
您的见解和智慧表示赞赏。
你知道,使用像dict这样的可变对象作为默认参数或者像__init__
方法之类的东西可能不会像你想象的那样表现。
举个简单的例子:
class A(object):
a = {'foo':1}
a = A()
a.a['bar'] = 2
b = A()
print b.a
所以现在, ba
是{'foo': 1, 'bar': 2}
,即使你希望它只是{'foo':1}
因此,将可变数据放在类的__init__
函数中是很常见的。 例如
class A(object):
def __init__(self):
self.a = {'foo':1}
a = A()
a.a['bar'] = 2
b = A()
print b.a
如果你定义:
class baseClass:
DataMap = {
'key1': 'val1',
'key2': 'val2',
'key3': 'val2',
}
然后baseClass.__dict__
包含'DataMap': {'key3': 'val2', 'key2': 'val2', 'key1': 'val1'}
。
这使得DataMap
无法涉及类继承,因为如果你以后定义的话
class subClass2(baseClass): # appends values to base DataMap
DataMap = {'key4':'val4'}
然后subClass2.__dict__
有自己的竞争条目与关键'DataMap'
。 如果s = subClass2()
是一个实例subClass2
,然后s.DataMap
将只访问DataMap
中subClass2.__dict__
并在找到它,就永远在寻找baseClass.__dict__
。 所以没有继承发生。
您可以在subClass2
修改baseClass.__dict__
,但这会违反OOP原则,因为子类不应该修改其父类。 这无论如何都不会是继承,因为对baseClass.__dict__
更改会影响baseClass
所有实例以及使用其DataMap
所有子类。
也许你可以通过DataMap
本身来实现你想要的东西:
class DataMap(object):
key1='val1'
key2='val2'
key3='val2'
class subDataMap(DataMap):
key4='val4'
class baseClass(object):
dataMap=DataMap
class subClass1(baseClass):
def myfunc(self,x):
val=getattr(self.dataMap,x)
if val == 'val2':
print 'foo'
class subClass2(baseClass):
dataMap=subDataMap
def myfunc(self,x):
val=getattr(self.dataMap,x)
if val == 'val4':
print 'foo'
elif val == 'val2':
print 'bar'
s=subClass1()
s.myfunc('key2')
# foo
try:
s.myfunc('key4')
except AttributeError as err:
print(err)
# subClass1 instance has no attribute 'key4'
s2=subClass2()
s2.myfunc('key2')
# bar
s2.myfunc('key4')
# foo
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.