繁体   English   中英

在python中使类数据可以继承的正确方法是什么?

[英]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将只访问DataMapsubClass2.__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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM