为什么属性引用像Python这样继承? [英] Why do attribute references act like this with Python inheritance?

查看:119
本文介绍了为什么属性引用像Python这样继承?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The following seems strange.. Basically, the somedata attribute seems shared between all the classes that inherited from 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 __ 函数显然是正确的方法来解决这个问题(所以每个类都有自己的

Defining self.somedata in the __init__ function is obviously the correct way to get around this (so each class has it's own somedata dict) - but when is such behavior desirable?

推荐答案

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

You are right, somedata is shared between all instances of the class and it's subclasses, because it is created at class definition time. The lines

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



< - (认为Java中的静态初始化程序块)。如果类实例中不存在某个属性,将检查类对象的属性。

are executed when the class is defined, i.e. when the interpreter encounters the class statement - not when the instance is created (think static initializer blocks in Java). If an attribute does not exist in a class instance, the class object is checked for the attribute.

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

At class definition time, you can run arbritrary code, like this:

 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 在所有其他系统上将打印其他字符串。

On a Linux system, Test().hello() will print Hello Linux, on all other systems the other string will be printed.

$ c> __ init __ 是在实例化时创建的,仅属于实例(当它们分配给 self 时) :

In constrast, objects in __init__ are created at instantiation time and belong to the instance only (when they are assigned to self):

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

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

Objects defined on a class object rather than instance can be useful in many cases. For instance, you might want to cache instances of your class, so that instances with the same member values can be shared (assuming they are supposed to be immutable):

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))

与元类或通用工厂方法相结合。

Mostly, I use data in class bodies in conjunction with metaclasses or generic factory methods.

这篇关于为什么属性引用像Python这样继承?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆