Singleton- python, Situation with the need of only one object - python

I am having a situation where I have to make sure I only have one object. I am thinking about implementing singleton like following:
class One_Of_a_Kind:
def __init__(self):
self.do_some_setup()
class One_Creator:
Only_One = None
def __new__(cls, *args, **kwargs):
if One_Creator.Only_One:
return One_Creator.Only_One
else:
One_Creator.Only_One = One_of_a_Kind()
return One_Creator.Only_One
Since I am reading a lot about singleton (pros and cons), I am little hesitant in implementing this code. I would like to know if it is okay and/or considered good practice to use in a situation where only one object of certain class in needed ( or mandatory).
Is there a better way of implementing the same thing?

A better way is the Borg design pattern. It's very simple to implement in python:
class Borg:
_shared_state = {}
def __init__(self):
self.__dict__ = self._shared_state
You don't actually have a single instance, but each instance shares the same state - which is the part that matters.

When and how to use a singleton is a pretty broad question and primarily opinion based. That being said, I would implement it like this:
class Singleton(object):
state = {}
def __init__(self):
self.__dict__ = Singleton.state
The idea is taken from here. This is sort of a pseudo-singleton, as two instance will not share the same id:
>>> s1 = Singleton()
>>> s2 = Singleton()
>>> s1 is s2
False
>>> s1.x = 42
>>> s2.x
42

Related

How to clone a python class object? (not the instance but the class itself)

Imagine you have the following code:
class A:
pass
NewA = ... # copy A
NewA.__init__ = decorator(A.__init__) # but don't change A's init function, just NewA's
I am looking for a way to change some of the attributes/methods in the cloned class and the rest I want them to be similar to the base class object (preferebly even through MappingProxyType so that when A changes the unchanged logic of NewA reflects the changes as well).
I came across this ancient thread, where there some suggetions which don't fully work:
Repurposing inheritance class NewA(A): pass which doesn't exactly result in what I am looking for
Dynamically generating a new class using type and somehow having an eye out for the tons of cases that might happen (having mutable attributes/descriptors/calls to globals ...)
Using copy.deepcopy which is totally wrong (since class object's internal data representation is a MappingProxyType which we cannot copy/deepcopy)
Is there a way to still achive this without manually handling every corner case, especially considering the fact that the base class we intend to copy could be anything (with metaclasses and custom init_subclass parents, and a mixture of attributes mutable and what not, and potentially with __slots__)?
Here is a humble attempt to get you started. I've tested it out with a class with slots and it seems to work. I am not very sure about that aspect of it though.
import types
import copy
def clone_class(klass):
def _exec_body(ns):
# don't add in slots descriptors, it will fail!
ns_no_slots = {
k:v for k,v in vars(klass).items()
if not isinstance(v, types.MemberDescriptorType)
}
ns |= copy.deepcopy(ns_no_slots)
return ns
return types.new_class(
name=klass.__name__,
bases=klass.__bases__,
kwds={"metaclass": type(klass)},
exec_body=_exec_body,
)
Now, this seems to work with classes that have __slots__. The one thing that might trip things up is if the metaclass has slots (which must be empty). But that would be really weird.
Here is a test script:
import types
import copy
def clone_class(klass):
def _exec_body(ns):
ns_no_slots = {
k:v for k,v in vars(klass).items()
if not isinstance(v, types.MemberDescriptorType)
}
ns |= copy.deepcopy(ns_no_slots)
return ns
return types.new_class(
name=klass.__name__,
bases=klass.__bases__,
kwds={"metaclass": type(klass)},
exec_body=_exec_body,
)
class Meta(type):
def meta_magic(cls):
print("magical!")
class Foo(metaclass=Meta):
__slots__ = ('x','y')
#property
def size(self):
return 42
class Bar(Foo):
state = []
__slots__ = ('z',)
def __init__(self, x=1, y=2, z=3):
self.x = x
self.y = y
self.z = z
#property
def closed(self):
return False
BarClone = clone_class(Bar)
bar = BarClone()
BarClone.state.append('foo')
print(BarClone.state, Bar.state)
BarClone.meta_magic()
This prints:
['foo'] []
magical!

Is using the __getattr__ method as a composition pattern good Python practice?

First - please accept my apologies if this is a duplicate - I have the feeling that I have seen some sort of similar discussion before, but I really cannot find it.
My question regards object composition in Python that should look like inheritance from within each minor of the composite classes. The use case is that multiple object instances share a common core of attributes and their values (and not only a common structure, which would be a classic inheritance case instead).
I could do this with a simple attribute, i.e. by simply having each Class having one attribute called "shared_attributes", which is in itself a class storing all the values:
class CoreClass(object):
def __init__(self):
self.attr = 'asdf'
class CompClass1(object):
def __init__(self, core):
self.core_attr = core
class CompClass2(object):
def __init__(self, core):
self.core_attr = core
But this requires me to access each shared attribute through the class.core_attr attribute, which I do not want (for several reasons, one of which is that this would require an extensive rewrite of large sections of code).
So, instead I would like to use a composite pattern relying on Python's built-in __getattr__ object method, as such:
class TestClass1(object):
def __init__(self):
self.attr1 = 1
def func_a(self):
return 'a'
class CompClassBase(object):
def __init__(self, test_class):
self.comp_obj = test_class
def __getattr__(self, item):
return getattr(self.comp_obj, item)
class CompClass1(CompClassBase):
def __init__(self, test_class):
CompClassBase.__init__(self, test_class)
self.attr2 = 13
def func_b(self):
return '1b'
class CompClass2(CompClassBase):
def __init__(self, test_class):
CompClassBase.__init__(self, test_class)
self.attr2 = 23
def func_b(self):
return '2b'
if __name__ == '__main__':
tc = TestClass1()
cc1 = CompClass1(test_class=tc)
cc2 = CompClass2(test_class=tc)
print cc1.attr1
print cc1.attr2
print cc1.func_a()
print cc1.func_b()
print cc2.attr1
print cc2.attr2
print cc2.func_a()
print cc2.func_b()
Which prints, as it should, the following:
1
13
a
1b
1
23
a
2b
This pattern fits my needs perfectly, but there is something about it that wants to make me be certain about it ...
EDIT: (to respond to some comments) It is essential that this pattern will share all attributes in the shared class (given the previous objects):
cc1.attr1 = 'this is a test'
cc2.attr1 # must now be 'this is a test' as well!
2nd EDIT: I have used this pattern now for several weeks, and it works beautifully. However, I'm still hoping for some discussion, since I want to include this pattern in my standard toolkit from now on :-)
So now my question to you is simple: Is this a good practice? Does this particular Python pattern have any disadvantages? Should I be aware of some dangers here?

Access class when used as class-level variable in Python

I do apologize if this question is already answered on SO or if my problem could be solved by a simple Google search, but I don't know the terminology to describe it, other than the question title, which didn't turn up any results.
Because I don't know the terminology, the best I can do is give an example of what I want.
class MyClassProperty():
def __init__(self):
# somehow access MyObject class
pass
class MyObject():
var = MyClassProperty()
MyClassProperty will not only need to reference the MyObject class, otherwise it would be simple. The end goal is to be able to automatically add methods and variables to the MyObject class when a MyClassProperty is instantiated at class level.
I have seen frameworks and libraries do this before, the one that first comes to mind is Kivy, with its properties.
Thanks for any help you can give, even if the extent of that help is to tell me this is impossible.
It looks like you might want traits.
The only existing Python implementation I could find on a cursory search is here: http://code.enthought.com/projects/traits.
Multiple inheritance might also work for you.
class Some(object):
a = 97
b = 98
def f(self):
return self.a + self.b + self.c
class Other(object):
c = 99
class Thing(Some, Other, object):
pass
o = Thing()
p = Thing()
p.a, p.b, p.c = 65, 66, 67
print o.a, o.b, o.c, o.f() # 97 98 99 294
print p.a, p.b, p.c, p.f() # 65 66 67 198
Explicit is better than implicit. The idiomatic way to handle composition is using "mixins":
class MyFooMixin():
def foo(self):
print("I have a foo")
class MyBarMixin():
def bar(self):
print("This is a bar, where is my beer?")
class MyObject(MyFooMixin, MyBarMixin):
pass
>>> x = MyObject()
>>> x.foo()
I have a foo
>>> x.bar()
This is a bar, where is my beer?
That said, at some implementations you can inspect the current frame. This is a naive approach to get you started (I'm sure it is wrong but I don't feel like digging all the frame structure stuff in order to write a proper implementation):
class Foo(object):
_instantiators = []
def __init__(self):
try:
raise Exception("foo")
except Exception as foo:
for frame in reversed(inspect.stack()):
try:
for line in frame[4]:
if line.startswith('class '):
class_name = re.match(r'class\s+(\S+?)\(', line).group(1)
self._instantiators.append(frame[0].f_globals[class_name])
break
except (IndexError, TypeError):
pass
class Bar(object):
foo = Foo()
if __name__ == '__main__':
bar = Bar()
print Foo._instantiators
This abominable hack will print:
[<class '__main__.Bar'>]
This is probably wrong in so many ways, but Python is very hackable (my second programming language was Lisp, after BASIC, in Python I miss lispy features like hygienic macros and tail call optimization).
I'm nor sure whether I got you correctly, but is this what you want?
class MyObject(object):
def __init__(self):
pass
def my_class_property(self):
self.property_a = []
self.property_b = 42
my_object = MyObject()
print my_object.property_a #fails
my_object.my_class_property()
print my_object.property_a
print my_object.property_b

Python singleton again / how to use class attributes?

I would like to have a singleton class in Python with Java like "static class attributes". I read the several posts existing on Python singletons and can not find a solution except using a simple module as singleton.
Is there a way to extends this code (PEP318) to use it with "static class attributes" that I can access from the functions?
def singleton(cls):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance
#singleton
class MyClass:
...
TBH, I've always found the singleton to be an anti-pattern.
If you want an object which will only ever have a single instance, then why bother even instantiating anything? Just do something like...
class MyCounter(object):
count = 0
#classmethod
def inc(cls, delta=1):
cls.count += delta
>>> MyCounter.count
0
>>> MyCounter.inc()
>>> MyCounter.count
1
>>> MyCounter.inc(5)
>>> MyCounter.count
6

Python singleton pattern

someone can tell me why this is incorrect as a singleton pattern:
class preSingleton(object):
def __call__(self):
return self
singleton = preSingleton()
# singleton is actually the singleton
a = singleton()
b = singleton()
print a==b
a.var_in_a = 100
b.var_in_b = 'hello'
print a.var_in_b
print b.var_in_a
Edit: The above code prints:
True
hello
100
thank you very much
Part Two
Maybe this is better?
class Singleton(object):
def __new__(cls):
return cls
a = Singleton()
b = Singleton()
print a == b
a.var_in_a = 100
b.var_in_b = 'hello'
print a.var_in_b
print b.var_in_a
Edit: The above code prints:
True
hello
100
Thanks again.
Singletons are actually really simple to make in Python. The trick is to have the module do your encapsulation for you and not make a class.
The module will only be initialized once
The module will not be initialized until the first time it is imported
Any attempts to re-import the module will return a pointer to the existing import
And if you want to pretend that the module is an instance of a class, you can do the following
import some_module
class SomeClass(object):
def __init__(self):
self.singleton = some_module
Because this is not a singleton. Singleton must be single, your object is not.
>>> class preSingleton(object):
... def __call__(self):
... return self
...
>>> singleton = preSingleton()
>>> singleton2 = preSingleton()
>>> singleton
<__main__.preSingleton object at 0x00C6D410>
>>> singleton2
<__main__.preSingleton object at 0x00C6D290>
This is actualy the Borg pattern. Multiple objects that share state.
That's not to say there's anything wrong with it, and for most if not all use cases it's functionaly equivalent to a singleton, but since you asked...
edit: Of course since they're Borg objects, each instance uses up more memory so if you're creating tons of them this will make a difference to resource usage.
Here's a sexy little singleton implemented as a decorator:
def singleton(cls):
"""Decorate a class with #singleton when There Can Be Only One."""
instance = cls()
instance.__call__ = lambda: instance
return instance
Use it like this:
#singleton
class MySingleton:
def spam(self):
print id(self)
What happens is that outside of the class definition, MySingleton will actually refer to the one and only instance of the class that exists, and you'll be left with no mechanism for creating any new instances. Calling MySingleton() will simply return the exact same instance. For example:
>>> MySingleton
<__main__.MySingleton instance at 0x7f474b9265a8>
>>> MySingleton()
<__main__.MySingleton instance at 0x7f474b9265a8>
>>> MySingleton() is MySingleton
True
>>> MySingleton.spam()
139944187291048
>>> MySingleton().spam()
139944187291048
I don't see the problem (if it walks like a duck and quacks like a duck...). Looks like a singleton to me.
It works differently from a Java singleton (for example) because Python uses the same syntax to call a function as to create a new instance of an object. So singleton() is actually calling the singleton object, which returns itself.
You can do this with your class:
>>> class preSingleton(object):
... def __call__(self):
... return self
...
>>> x = preSingleton()
>>> y = preSingleton()
>>> x == y
False
So, more than one instances of the class can be created and it violates the Singleton pattern.

Categories

Resources