当前位置:  开发笔记 > 编程语言 > 正文

为什么属性引用与Python继承一样?

如何解决《为什么属性引用与Python继承一样?》经验,为你挑选了2个好方法。

以下看起来很奇怪..基本上,somedata属性似乎在所有继承的类之间共享the_base_class.

class the_base_class:
    somedata = {}
    somedata['was_false_in_base'] = False


class subclassthing(the_base_class):
    def __init__(self):
            print self.somedata


first = subclassthing()
{'was_false_in_base': False}
first.somedata['was_false_in_base'] = True
second = subclassthing()
{'was_false_in_base': True}
>>> del first
>>> del second
>>> third = subclassthing()
{'was_false_in_base': True}

self.somedata__init__函数中定义显然是解决这个问题的正确方法(所以每个类都有它自己的somedatadict) - 但什么时候这种行为是可取的?



1> Torsten Mare..:

你是对的,somedata在类的所有实例和它的子类之间共享,因为它是在类定义时创建的.线条

somedata = {}
somedata['was_false_in_base'] = False

在定义类时执行,即当解释器遇到class语句时 - 而不是在创建实例时(在Java中考虑静态初始化程序块).如果类实例中不存在属性,则会检查类对象的属性.

在类定义时,您可以运行arbritrary代码,如下所示:

 import sys
 class Test(object):
     if sys.platform == "linux2":
         def hello(self):
              print "Hello Linux"
     else:
         def hello(self):
              print "Hello ~Linux"

在Linux系统上,Test().hello()将打印Hello Linux,在所有其他系统上将打印另一个字符串.

相反,对象in __init__实例化时创建并且仅属于实例(当它们被分配时self):

class Test(object):
    def __init__(self):
        self.inst_var = [1, 2, 3]

在类对象而不是实例上定义的对象在许多情况下都很有用.例如,您可能希望缓存类的实例,以便可以共享具有相同成员值的实例(假设它们应该是不可变的):

class SomeClass(object):
    __instances__ = {}

    def __new__(cls, v1, v2, v3):
        try:
            return cls.__insts__[(v1, v2, v3)]
        except KeyError:
            return cls.__insts__.setdefault(
               (v1, v2, v3), 
               object.__new__(cls, v1, v2, v3))

大多数情况下,我将类体中的数据与元类或通用工厂方法结合使用.



2> TimB..:

请注意,您所看到的部分行为是由于somedata是a dict,而不是简单的数据类型,如a bool.

例如,请看这个行为不同的不同示例(尽管非常相似):

class the_base_class:
    somedata = False

class subclassthing(the_base_class):
    def __init__(self):
        print self.somedata


>>> first = subclassthing()
False
>>> first.somedata = True
>>> print first.somedata
True
>>> second = subclassthing()
False
>>> print first.somedata
True
>>> del first
>>> del second
>>> third = subclassthing()
False

本实施例中从在问题给出的行为不同的原因是因为在这里first.somedata被给定一个新的值(对象True),而在第一个例子中通过引用的字典对象first.somedata(并且还通过其他子类实例)被修改.

有关进一步说明,请参阅Torsten Marek对此答案的评论.

推荐阅读
跟我搞对象吧
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有