python oop 继承_关于oop:使类数据在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想到,直接类数据访问是常见的,并且由于调用方法的开销而受到大多数鼓励。我感觉这种方法虽然不是很Python,但是我想进行一次健全性检查。

DataMap是否应该驻留在一个类函数中,尽管该类一旦编译后就不会改变,那么当继承BaseClass和subClass2时,subClass1可以通过一个类方法获取该数据,而subClass2可以覆盖同一方法以将其datamap与base附加/合并。

感谢您的见解和智慧。

如果您定义:

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将仅访问subClass2.__dict__中的DataMap,并且在找到它时将永远不会在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

我在示例中展示了一个DataMap,但实际上我正在查看出于各种目的应由所有对象共享的多个数据图。 我认为在我的"真实世界"中,这种解决方案会变得混乱吗?

@tima:是的; 它会变得凌乱。 在那种情况下,要使用类属性并获得继承的好处,我认为最好使DataMap成为一个类,并通过子类化DataMap将新的键值添加到数据映射中。

众所周知,将像dict这样的可变对象用作默认参数,或者在诸如__init__方法之类的东西之外使用行为,可能不会像您认为的那样起作用。

作为一个简单的例子:

class A(object):

a = {'foo':1}

a = A()

a.a['bar'] = 2

b = A()

print b.a

因此,即使您希望b.a只是{'foo':1},b.a还是{'foo': 1, 'bar': 2}

因此,通常将可变数据放入类的__init__函数中。例如。

class A(object):

def __init__(self):

self.a = {'foo':1}

a = A()

a.a['bar'] = 2

b = A()

print b.a

是的,您的第一个示例不像我想的那样有效。 我希望拥有该类的所有对象共享的不可变数据集。 第二个示例是为每个不必要的对象实例创建数据副本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值