Why is this Python Borg / Singleton pattern working - python

i just stumbled around the net and found these interesting code snipped:
http://code.activestate.com/recipes/66531/
class Borg:
__shared_state = {}
def __init__(self):
self.__dict__ = self.__shared_state
# and whatever else you want in your class -- that's all!
I understand what a singleton is but i don't understand that particular code snipped.
Could you explain me how/where "__shared_state" is even changed at all?
I tried it in ipython:
In [1]: class Borg:
...: __shared_state = {}
...: def __init__(self):
...: self.__dict__ = self.__shared_state
...: # and whatever else you want in your class -- that's all!
...:
In [2]: b1 = Borg()
In [3]: b2 = Borg()
In [4]: b1.foo="123"
In [5]: b2.foo
Out[5]: '123'
In [6]:
but cannot fully understand how this could happen.

Because the class's instance's __dict__ is set equal to the __share_state dict. They point to the same object. (Classname.__dict__ holds all of the class attributes)
When you do:
b1.foo = "123"
You're modifying the dict that both b1.__dict__ and Borg.__shared_state refer to.

The __init__ method, which is called after instantiating any object, replaces the __dict__ attribute of the newly created object with the class attribute __shared_state.
a.__dict__, b.__dict__ and Borg._Borg__shared_state are all the same object. Note that we have to add the implicit prefix _Borg when accessing private attribute from outside the class.
In [89]: a.__dict__ is b.__dict__ is Borg._Borg__shared_state
Out[89]: True

The instances are separate objects, but by setting their __dict__ attributes to the same value, the instances have the same attribute dictionary. Python uses the attribute dictionary to store all attributes on an object, so in effect the two instances will behave the same way because every change to their attributes is made to the shared attribute dictionary.
However, the objects will still compare unequal if using is to test equality (shallow equality), since they are still distinct instances (much like individual Borg drones, which share their thoughts but are physically distinct).

Related

How do I override __type__ method in python object?

I create a Python class for some mathematical calculations. In that object, I am trying to change type(type) methods result. And my attempts failed.
When I try type() method for my object that appears
<class '__main__.MyClassName'>
I override type method in my method :
class MyMathOBJ():
.
.
.
def __type__(self):
return "MyMathOBJ"
But when I do that nothing changed. The same result. I was expecting just that result MyMathOBJ.
You seem to fundamentally misunderstand what type does. type itself is just a class, a metaclass. When you call type on an instance, it returns the class object that corresponds to that instance, pretty much equivalent to instance.__class__. However, you simply want to change the way the class object is represented when you print it, so you'd need to implement a metaclass for MyMathOBJ that overrides __repr__ in the metaclass to accomplish this.
Here is how you accomplish what you are actually trying to do:
In [12]: class PrettyType(type):
...: def __repr__(self):
...: return self.__name__
...:
In [13]: class MyMathOBJ(metaclass=PrettyType):
...: pass
...:
In [14]: obj = MyMathOBJ()
In [15]: obj
Out[15]: <MyMathOBJ at 0x1060cbcc0>
In [16]: type(obj)
Out[16]: MyMathOBJ

Subclassing a class that implements singleton thought metaclass

I have this code:
class Singleton(type):
def __call__(cls,*args,**kwargs):
if cls.created is None :
print('called')
cls.created = super().__call__(*args,**kwargs)
return cls.created
else:
return cls.created
def __new__(cls,name,base,attr,**kwargs):
return super().__new__(cls,name,base,attr,**kwargs)
class OnlyOne(metaclass=Singleton):
created = None
def __init__(self,val):
self.val = val
class OnlyOneTwo(OnlyOne):
pass
k = OnlyOne(1)
a = OnlyOneTwo(2)
print(a.val)
print(k.val)
print('a.created: {0} - b.created: {1}'.format(id(a.created),id(k.created)))
I'm new to Python 3 so I decided to do some little experiment and playing around Python's metaclasses.
Here, I attempted to make a metaclass that will strict a class to a single instance when set.
I'm not sure yet if this works but whenever I try to do:
k = OnlyOne(1)
a = OnlyOneTwo(2)
the output will be:
called
1
1
which means that OnlyOneTwo wasn't set but when I try to do:
a = OnlyOneTwo(2)
k = OnlyOne(1)
the output will be:
called
called
2
1
Can someone help me traceback? I'm somehow confused but here are my initial questions/thoughts:
Does OnlyOneTwo's created property the same as OnlyOne's ? because I get different results through id() depending on which one I defined first. It's different if it's OnlyOneTwo first but it's the same if it's OnlyOne first.
How come created is still None if I will run a = OnlyOneTwo(2)
print(OnlyOne.created) ?
I'll give this a shot. I think the symptom is due to the assignment, cls.created = ... in __call__.
When the class objects are first created OnlyOneTwo.created points to OnlyOne.created. They both have the same id, which is the same as None.
>>> id(None)
506773144
>>> id(OnlyOne.created), id(OnlyOneTwo.created)
(506773144, 506773144)
If you make an instance of OnlyOne first, the instance is assigned to OnlyOne.created (it no longer points to None) but OnlyOneTwo.created still points to OnlyOne.created - they are still the same thing so that when OnlyOneTwo is called, the else clause of the conditional is executed.
>>> a = OnlyOne('a')
called
>>> id(OnlyOne.created), id(OnlyOneTwo.created)
(54522152, 54522152)
>>> z = OnlyOneTwo('z')
>>> id(OnlyOne.created), id(OnlyOneTwo.created)
(54522152, 54522152)
>>> id(a)
54522152
When you make an instance of OnlyOneTwo first, that instance is assigned to OnlyOneTwo.created, it no longer points to OnlyOne.created. OnlyOne.created still points to None.
>>> id(None)
506773144
>>> id(OnlyOne.created), id(OnlyOneTwo.created)
(506773144, 506773144)
>>> z = OnlyOneTwo('z')
called
>>> id(OnlyOne.created), id(OnlyOneTwo.created)
(506773144, 54837544)
>>> id(z)
54837544
Now when you make an instance of OnlyOne the if condition is True and the instance is assigned to OnlyOne.created
>>> a = OnlyOne('a')
called
>>> id(OnlyOne.created), id(OnlyOneTwo.created)
(54352752, 54837544)
>>> id(a)
54352752
I often find myself re-reading Binding of Names and Resolution of Names - also A Word About Names and Objects and Python Scopes and Namespaces
I feel that I haven't actually explained the mechanism - I don't really understand how the child class attribute points to the base class attribute - it is something different than a = b = None.
Maybe:
Initially the child class doesn't actually have the attribute, the points to mechanism is how inheritance is implemented, since it doesn't have the attribute, the attribute is searched for in its parent(s).
Even though the parent class attribute changes with instantiation, the child class still doesn't have the attribute and has to search for it and it finds the new thing.
If the child class is instantiated first the assignment in the metaclass gives the attribute to the child class - now it has it and it doesn't have to search for it.
Re-reading the Custom Classes section of the Standard Type Hierarchy in the docs triggered that brain dump.
I feel like I've been here before, maybe even in SO. Hope I remember it this time and don't have to figure it out again.
If you want to fix your Singleton there are numerous options if you search for them. Using a metaclass it seems the instance is held in the metaclass, not the the class itself. Creating a singleton in Python, SO Q&A, is a good start.

class initialization in Python

I found that some classes contain a __init__ function, and some don’t. I’m confused about something described below.
What is the difference between these two pieces of code:
class Test1(object):
i = 1
and
class Test2(object):
def __init__(self):
self.i = 1
I know that the result or any instance created by these two class and the way of getting their instance variable are pretty much the same. But is there any kind of “default” or “hidden” initialization mechanism of Python behind the scene when we don’t define the __init__ function for a class? And why I can’t write the first code in this way:
class Test1(object):
self.i = 1
That’s my questions. Thank you very much!
Thank you very much Antti Haapala! Your answer gives me further understanding of my questions. Now, I understand that they are different in a way that one is a "class variable", and the other is a "instance variable". But, as I tried it further, I got yet another confusing problem.
Here is what it is. I created 2 new classes for understanding what you said:
class Test3(object):
class_variable = [1]
def __init__(self):
self.instance_variable = [2]
class Test4(object):
class_variable = 1
def __init__(self):
self.instance_variable = 2
As you said in the answer to my first questions, I understand the class_variable is a "class variable" general to the class, and should be passed or changed by reference to the same location in the memory. And the instance_variable would be created distinctly for different instances.
But as I tried out, what you said is true for the Test3's instances, they all share the same memory. If I change it in one instance, its value changes wherever I call it.
But that's not true for instances of Test4. Shouldn't the int in the Test4 class also be changed by reference?
i1 = Test3()
i2 = Test3()
>>> i1.i.append(2)
>>> i2.i
[1, 2]
j1 = Test4()
j2 = Test4()
>>> j1.i = 3
>>> j2.i
1
Why is that? Does that "=" create an "instance variable" named "i" without changing the original "Test4.i" by default? Yet the "append" method just handles the "class variable"?
Again, thank you for your exhaustive explanation of the most boring basic concepts to a newbie of Python. I really appreciate that!
In python the instance attributes (such as self.i) are stored in the instance dictionary (i.__dict__). All the variable declarations in the class body are stored as attributes of the class.
Thus
class Test(object):
i = 1
is equivalent to
class Test(object):
pass
Test.i = 1
If no __init__ method is defined, the newly created instance usually starts with an empty instance dictionary, meaning that none of the properties are defined.
Now, when Python does the get attribute (as in print(instance.i) operation, it first looks for the attribute named i that is set on the instance). If that fails, the i attribute is looked up on type(i) instead (that is, the class attribute i).
So you can do things like:
class Test:
i = 1
t = Test()
print(t.i) # prints 1
t.i += 1
print(t.i) # prints 2
but what this actually does is:
>>> class Test(object):
... i = 1
...
>>> t = Test()
>>> t.__dict__
{}
>>> t.i += 1
>>> t.__dict__
{'i': 2}
There is no i attribute on the newly created t at all! Thus in t.i += 1 the .i was looked up in the Test class for reading, but the new value was set into the t.
If you use __init__:
>>> class Test2(object):
... def __init__(self):
... self.i = 1
...
>>> t2 = Test2()
>>> t2.__dict__
{'i': 1}
The newly created instance t2 will already have the attribute set.
Now in the case of immutable value such as int there is not that much difference. But suppose that you used a list:
class ClassHavingAList():
the_list = []
vs
class InstanceHavingAList()
def __init__(self):
self.the_list = []
Now, if you create 2 instances of both:
>>> c1 = ClassHavingAList()
>>> c2 = ClassHavingAList()
>>> i1 = InstanceHavingAList()
>>> i2 = InstanceHavingAList()
>>> c1.the_list is c2.the_list
True
>>> i1.the_list is i2.the_list
False
>>> c1.the_list.append(42)
>>> c2.the_list
[42]
c1.the_list and c2.the_list refer to the exactly same list object in memory, whereas i1.the_list and i2.the_list are distinct. Modifying the c1.the_list looks as if the c2.the_list also changes.
This is because the attribute itself is not set, it is just read. The c1.the_list.append(42) is identical in behaviour to
getattr(c1, 'the_list').append(42)
That is, it only tries read the value of attribute the_list on c1, and if not found there, then look it up in the superclass. The append does not change the attribute, it just changes the value that the attribute points to.
Now if you were to write an example that superficially looks the same:
c1.the_list += [ 42 ]
It would work identical to
original = getattr(c1, 'the_list')
new_value = original + [ 42 ]
setattr(c1, 'the_list', new_value)
And do a completely different thing: first of all the original + [ 42 ] would create a new list object. Then the attribute the_list would be created in c1, and set to point to this new list. That is, in case of instance.attribute, if the attribute is "read from", it can be looked up in the class (or superclass) if not set in the instance, but if it is written to, as in instance.attribute = something, it will always be set on the instance.
As for this:
class Test1(object):
self.i = 1
Such thing does not work in Python, because there is no self defined when the class body (that is all lines of code within the class) is executed - actually, the class is created only after all the code in the class body has been executed. The class body is just like any other piece of code, only the defs and variable assignments will create methods and attributes on the class instead of setting global variables.
I understood my newly added question. Thanks to Antti Haapala.
Now, when Python does the get attribute (as in print(instance.i) operation, it first looks for the attribute named i that is set on the instance). If that fails, the i attribute is looked up on type(i) instead (that is, the class attribute i).
I'm clear about why is:
j1 = Test4()
j2 = Test4()
>>> j1.i = 3
>>> j2.i
1
after few tests. The code
j1.3 = 3
actually creates a new instance variable for j1 without changing the class variable. That's the difference between "=" and methods like "append".
I'm a newbie of Python coming from c++. So, at the first glance, that's weird to me, since I never thought of creating a new instance variable which is not created in the class just using the "=". It's really a big difference between c++ and Python.
Now I got it, thank you all.

What is the dfifference between instance dict and class dict

I was reading the python descriptors and there was one line there
Python first looks for the member in the instance dictionary. If it's
not found, it looks for it in the class dictionary.
I am really confused what is instance dict and what is class dictionary
Can anyone please explain me with code what is that
I was thinking of them as same
An instance dict holds a reference to all objects and values assigned to the instance, and the class level dict holds all references at the class namespace.
Take the following example:
>>> class A(object):
... def foo(self, bar):
... self.zoo = bar
...
>>> i = A()
>>> i.__dict__ # instance dict is empty
{}
>>> i.foo('hello') # assign a value to an instance
>>> i.__dict__
{'zoo': 'hello'} # this is the instance level dict
>>> i.z = {'another':'dict'}
>>> i.__dict__
{'z': {'another': 'dict'}, 'zoo': 'hello'} # all at instance level
>>> A.__dict__.keys() # at the CLASS level, only holds items in the class's namespace
['__dict__', '__module__', 'foo', '__weakref__', '__doc__']
I think, you can understand with this example.
class Demo(object):
class_dict = {} # Class dict, common for all instances
def __init__(self, d):
self.instance_dict = d # Instance dict, different for each instance
And it's always possible to add instance attribute on the fly like this: -
demo = Demo({1: "demo"})
demo.new_dict = {} # A new instance dictionary defined just for this instance
demo2 = Demo({2: "demo2"}) # This instance only has one instance dictionary defined in `init` method
So, in the above example, demo instance has now 2 instance dictionary - one added outside the class, and one that is added to each instance in __init__ method. Whereas, demo2 instance has just 1 instance dictionary, the one added in __init__ method.
Apart from that, both the instances have a common dictionary - the class dictionary.
Those dicts are the internal way of representing the object or class-wide namespaces.
Suppose we have a class:
class C(object):
def f(self):
print "Hello!"
c = C()
At this point, f is a method defined in the class dict (f in C.__dict__, and C.f is an unbound method in terms of Python 2.7).
c.f() will make the following steps:
look for f in c.__dict__ and fail
look for f in C.__dict__ and succeed
call C.f(c)
Now, let's do a trick:
def f_french():
print "Bonjour!"
c.f = f_french
We've just modified the object's own dict. That means, c.f() will now print Bounjour!. This does not affect the original class behaviour, so that other C's instances will still speak English.
Class dict is shared among all the instances (objects) of the class, while each instance (object) has its own separate copy of instance dict.
You can define attributes separately on a per instance basis rather than for the whole class
For eg.
class A(object):
an_attr = 0
a1 = A()
a2 = A()
a1.another_attr = 1
Now a2 will not have another_attr. That is part of the instance dict rather than the class dict.
Rohit Jain has the simplest python code to explain this quickly. However, understanding the same ideas in Java can be useful, and there is much more information about class and instance variables here

Difference between defining a member in __init__ to defining it in the class body in python?

What is the difference between doing
class a:
def __init__(self):
self.val=1
to doing
class a:
val=1
def __init__(self):
pass
class a:
def __init__(self):
self.val=1
this creates a class (in Py2, a cruddy, legacy, old-style, don't do that! class; in Py3, the nasty old legacy classes have finally gone away so this would be a class of the one and only kind -- the **good* kind, which requires class a(object): in Py2) such that each instance starts out with its own reference to the integer object 1.
class a:
val=1
def __init__(self):
pass
this creates a class (of the same kind) which itself has a reference to the integer object 1 (its instances start out with no per-instance reference).
For immutables like int values, it's hard to see a practical difference. For example, in either case, if you later do self.val = 2 on one instance of a, this will make an instance reference (the existing answer is badly wrong in this respect).
The distinction is important for mutable objects, because they have mutator methods, so it's pretty crucial to know if a certain list is unique per-instance or shared among all instances. But for immutable objects, since you can never change the object itself but only assign (e.g. to self.val, which will always make a per-instance reference), it's pretty minor.
Just about the only relevant difference for immutables: if you later assign a.val = 3, in the first case this will affect what's seen as self.val by each instance (except for instances that had their own self.val assigned to, or equivalent actions); in the second case, it will not affect what's seen as self.val by any instance (except for instances for which you had performed del self.val or equivalent actions).
Others have explained the technical differences. I'll try to explain why you might want to use class variables.
If you're only instantiating the class once, then class variables effectively are instance variables. However, if you're making many copies, or want to share state among a few instances, then class variables are very handy. For example:
class Foo(object):
def __init__(self):
self.bar = expensivefunction()
myobjs = [Foo() for _ in range(1000000)]
will cause expensivefunction() to be called a million times. If it's going to return the same value each time, say fetching a configuration parameter from a database, then you should consider moving it into the class definition so that it's only called once and then shared across all instances.
I also use class variables a lot when memoizing results. Example:
class Foo(object):
bazcache = {}
#classmethod
def baz(cls, key):
try:
result = cls.bazcache[key]
except KeyError:
result = expensivefunction(key)
cls.bazcache[key] = result
return result
In this case, baz is a class method; its result doesn't depend on any instance variables. That means we can keep one copy of the results cache in the class variable, so that 1) you don't store the same results multiple times, and 2) each instance can benefit from results that were cached from other instances.
To illustrate, suppose that you have a million instances, each operating on the results of a Google search. You'd probably much prefer that all those objects share those results than to have each one execute the search and wait for the answer.
So I'd disagree with Lennart here. Class variables are very convenient in certain cases. When they're the right tool for the job, don't hesitate to use them.
As mentioned by others, in one case it's an attribute on the class on the other an attribute on the instance. Does this matter? Yes, in one case it does. As Alex said, if the value is mutable. The best explanation is code, so I'll add some code to show it (that's all this answer does, really):
First a class defining two instance attributes.
>>> class A(object):
... def __init__(self):
... self.number = 45
... self.letters = ['a', 'b', 'c']
...
And then a class defining two class attributes.
>>> class B(object):
... number = 45
... letters = ['a', 'b', 'c']
...
Now we use them:
>>> a1 = A()
>>> a2 = A()
>>> a2.number = 15
>>> a2.letters.append('z')
And all is well:
>>> a1.number
45
>>> a1.letters
['a', 'b', 'c']
Now use the class attribute variation:
>>> b1 = B()
>>> b2 = B()
>>> b2.number = 15
>>> b2.letters.append('z')
And all is...well...
>>> b1.number
45
>>> b1.letters
['a', 'b', 'c', 'z']
Yeah, notice that when you changed, the mutable class attribute it changed for all classes. That's usually not what you want.
If you are using the ZODB, you use a lot of class attributes because it's a handy way of upgrading existing objects with new attributes, or adding information on a class level that doesn't get persisted. Otherwise you can pretty much ignore them.

Categories