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

时间:2015-05-12 22:13:12

标签: python oop static-variables

I need a way to create a static class variable in Python that only the class will have. 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:

NSArray *anArray = [NSArray array];
NSIndexSet *anIndexSet = [NSIndexSet indexSetWithIndex:3];
NSUInteger index = [anIndexSet firstIndex];

while(index != NSNotFound) {
      NSLog(@" %@",[anArray objectAtIndex:index]);
      index = [anIndexSet indexGreaterThanIndex:index];
}

In other words, I'm looking for a static class variable like in PHP:

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

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?

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.

2 个答案:

答案 0 :(得分:4)

the static class variable suggested is created for each instance

That is false, as you can easily demonstrate:

int[] myIntArray = {numDemocrats, numRepub, numIndep};
return myIntArray;

However, you can override the class attribute with an instance attribute:

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

so if you need to replace the class attribute (rather than alter it in-place, as the >>> t1.class_attr = [] >>> t1.class_attr is t2.class_attr False did) you should do so via the class, not the instance (in this case, append would have affected both Test.class_attr = [] and t1).

答案 1 :(得分:1)

  response.code >= 200 && response.code < 400

All attributes of a class are stored in class MyClass(): i = 1 inst = MyClass() . It contains __dict__ (in addition to a bunch of other things):

i

The instance does not have any attributes:

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

If >>> inst.__dict__ {} cannot be found in i the search continues in inst.__dict__. Even though it looks a bit like the instance has an attribute MyClass.__dict__, it actually exist in the class only.

As soon as you assign to the instance:

i

the this changes:

inst.i = 10

Now, the instance has its own attribute.