简体   繁体   English

Python中的静态类变量不会为每个实例复制

[英]Static class variable in Python that isn't copied for each instance

I need a way to create a static class variable in Python that only the class will have. 我需要一种在Python中创建仅该类具有的静态类变量的方法。 I can't afford this variable to be created over and over again for each instance, because the target class variable will be a huge read-only data structure. 我无法为每个实例一遍又一遍地创建此变量,因为目标类变量将是巨大的只读数据结构。 Each instance must be able to access it for read-only purposes throught the class, but since it's a giant bulk of data and there will be thousands instances, I can't afford that each instance will create another copy of this data structure again. 每个实例都必须能够出于整个类的只读目的对其进行访问,但是由于它是大量数据,并且将有成千上万个实例,因此我无法承受每个实例将再次创建此数据结构的另一个副本的情况。

I found this question , but it doesn't solve my problem, because the static class variable suggested is created for each instance: 我找到了这个问题 ,但并不能解决我的问题,因为建议的静态类变量是为每个实例创建的:

>>> class MyClass():
    i = 1
>>> m = MyClass()
>>> m.i
1

In other words, I'm looking for a static class variable like in PHP: 换句话说,我正在寻找一个类似PHP的静态类变量:

<?php
class Foo
{
    public static $my_static = 'foo';
}

$foo = new Foo();
print $foo::$my_static . "\n";     // Accessable throught the class
print $foo->my_static . "\n";      // Undefined "Property" my_static     
?>

This is exactly what I need, the static class variable is created only once for the class, all instances can access it throught the class but this static class variable isn't created over and over for each new instance. 这正是我所需要的,静态类变量仅为该类创建一次,所有实例都可以在整个类中访问它,但不会为每个新实例一遍又一遍地创建此静态类变量。 Is it possible to create a static class variable like this in Python? 是否可以在Python中创建像这样的静态类变量?

PS: I now there are some workarounds if I don't use OOP, but if I could find a good and clearly readable OOP solution it would make more sense in the project as a whole. PS:如果不使用OOP,我现在有一些解决方法,但是,如果我能找到一个好的且清晰易读的OOP解决方案,那么在整个项目中就更有意义了。

the static class variable suggested is created for each instance 建议的静态类变量是为每个实例创建的

That is false, as you can easily demonstrate: 这是错误的,因为您可以轻松地演示:

>>> class Test():
    class_attr = []


>>> t1 = Test()
>>> t2 = Test()
>>> t1.class_attr is t2.class_attr
True  # this means that they reference exactly the same object
>>> t1.class_attr.append(1)  # alter via t1
>>> t2.class_attr
[1]  # see the changes via t2

However, you can override the class attribute with an instance attribute: 但是,您可以使用实例属性覆盖 class属性:

>>> t1.class_attr = []
>>> t1.class_attr is t2.class_attr
False

so if you need to replace the class attribute (rather than alter it in-place, as the append did) you should do so via the class, not the instance (in this case, Test.class_attr = [] would have affected both t1 and t2 ). 因此,如果您需要替换类属性(而不是像append那样就地更改它),则应通过类而不是实例(在这种情况下, Test.class_attr = []会同时影响t1 t2 )。

class MyClass():
    i = 1

inst = MyClass()

All attributes of a class are stored in __dict__ . 类的所有属性都存储在__dict__ It contains i (in addition to a bunch of other things): 它包含i (除了一堆其他东西):

>>> MyClass.__dict__
mappingproxy({'__weakref__': <attribute '__weakref__' of 'MyClass' objects>,
'__module__': '__main__', '__dict__': <attribute '__dict__' of 'MyClass'
 objects>, 'i': 1, '__doc__': None})

The instance does not have any attributes: 该实例没有任何属性:

>>> inst.__dict__
{}

If i cannot be found in inst.__dict__ the search continues in MyClass.__dict__ . 如果在inst.__dict__找不到i则在MyClass.__dict__继续搜索。 Even though it looks a bit like the instance has an attribute i , it actually exist in the class only. 即使看起来实例具有属性i ,它实际上仅存在于类中。

As soon as you assign to the instance: 分配给实例后:

inst.i = 10

the this changes: 这个改变:

>>> inst.__dict__
{'i': 10}

Now, the instance has its own attribute. 现在,实例具有其自己的属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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