Here is the scenario. I have a class Foo that looks like this:
class Foo:
def __init__(self, prop):
self.prop = prop
def method(self):
if self.prop == PROP_VAL_1:
do_something()
elif self.prop == PROP_VAL_2:
do_something_2()
else:
raise ValueError(f"Invalid value {self.prop}")
I want to do a refactor in which I end up with two subclasses of Foo like this:
class FooA(Foo):
def method():
do_something()
class FooB(Foo):
def method():
do_something_2()
However, the issue is that I can't change how Foo is used because there is code currently in use that uses Foo. Is it possible to somehow have the superclass Foo instantiate objects of type FooA and FooB depending on the value of prop? Another thing I want to avoid is having Foo import it's subclasses since this would lead to circular dependencies. Is there some sort of "best practice" for this as well?
Rename the Foo class, then replace it with a factory function.
class NewFoo:
def __init__(self, prop):
self.prop = prop
class FooA(NewFoo):
def method():
do_something()
class FooB(NewFoo):
def method():
do_something_2()
def Foo(prop):
if prop == PROP_VAL_1:
return FooA(prop)
elif prop == PROP_VAL_2:
return FooB(prop)
By definition, you want the class Foo to return an instance that is not Foo, but a subclass of Foo.
I would caution against this, as it may be surprising to the users of your class.
You have a few options:
You can use a factory function, as #Barmar suggests but use a name such as foo_factory and keep the method Foo.method intact with some aggressive logging. This allows you to incrementally change all call sites from Foo to foo_factory and have the logging as peace of mind that no one is directly instantiating Foo anymore.
Another option is to modify Foo.__new__ to return an instance of a subclass:
I modified your code a bit to an MRE.
PROP_VAL_1 = 1
PROP_VAL_2 = 2
class Foo:
def __new__(cls, prop):
# if the class was instantiated directly
if cls is Foo:
if prop == PROP_VAL_1:
return FooA(prop)
elif prop == PROP_VAL_2:
return FooB(prop)
else:
raise ValueError(f"Invalid value {prop}")
# this is only reached if a subclass is instantiated
return super().__new__(cls)
def __init__(self, prop):
self.prop = prop
class FooA(Foo):
def method(self):
return 'do_something'
class FooB(Foo):
def method(self):
return 'do_something_2'
foo = Foo(prop=2)
print(isinstance(foo, Foo)) # True
print(type(foo)) # <class '__main__.FooB'>
print(foo.method()) # do_something_2
There is a simplified code I have:
class A:
def foo(*args, **kwargs):
def foo_sub(*args, **kwargs):
print(f"foo args: {args}")
return foo_sub
def bar(*args, **kwargs):
print(f"bar args: {args}")
a = A()
class B:
foo = a.foo(1)
bar = a.bar
a.foo(2)()
a.bar()
B.foo()
B.bar()
B().foo()
B().bar()
And there is output:
foo args: ()
bar args: (<__main__.A object at 0x7f9763e38080>,)
foo args: ()
bar args: (<__main__.A object at 0x7f9763e38080>,)
foo args: (<__main__.B object at 0x7f9763e38828>,)
bar args: (<__main__.A object at 0x7f9763e38080>,)
I need to wrap foo func in A class and I really don't understand why does B().foo() passes self as argument? How can I prevent it?
More complicated code example: https://codehs.com/sandbox/id/python-3-2uVmcT
I don't know what you are trying to do here with all this wrappers and stuff. You might want to look at decorators or context managers to cleanly do this.
https://docs.python.org/3/glossary.html#term-decorator
https://docs.python.org/3/reference/compound_stmts.html#grammar-token-decorator
https://docs.python.org/3/library/functools.html#functools.wraps
https://docs.python.org/3/library/stdtypes.html#context-manager-types
Answering your question, one way of doing this is by defining static methods as also already pointed out by #MisterMiyagi. Generally in programming, static methods are methods of a class that you can call without needing a class instance/object. This means that such methods has no reference to a class instance's/object's state (in the form of class attributes/fields). In Python, ordinary class methods has access to the instance/object itself via this automatic self argument. If you don't want it, define it as a #staticmethod instead.
A static method does not receive an implicit first argument.
Which is by practice named self.
https://docs.python.org/3/library/functions.html#staticmethod
If you access a method (a function defined in a class namespace)
through an instance, you get a special object: a bound method (also
called instance method) object. When called, it will add the self
argument to the argument list.
"Through an instance" as how you did with B() to do B().foo().
https://docs.python.org/3/library/stdtypes.html#methods
Quick code to solve your case (note that as I pointed out earlier, there are better alternatives to this):
class A:
#staticmethod # Or use the inline-decorator stlye as #kaya3 mentioned
def foo(*args, **kwargs):
def foo_sub(*args, **kwargs):
print(f"foo args: {args}")
return foo_sub
#staticmethod
def bar(*args, **kwargs):
print(f"bar args: {args}")
a = A()
class B:
#staticmethod
def foo(*args, **kwargs):
return a.foo(1)(*args, **kwargs)
#staticmethod
def bar(*args, **kwargs):
return a.bar(*args, **kwargs)
a.foo(2)()
a.bar()
B.foo()
B.bar()
B().foo()
B().bar()
Output:
foo args: ()
bar args: ()
foo args: ()
bar args: ()
foo args: ()
bar args: ()
Otherwise if you really badly want to skip the self attribute altogether and hack all the way through, you could trigger obj.method.__func__(*args, **kwargs) as described in https://docs.python.org/3/library/stdtypes.html#methods
WARNING: This suggestion is hackish. Proceed with caution :)
Thanks #kaya3 for giving a good idea with staticmethod and also everyone who replied!
I found a solution with metaclass
class BMeta(type):
def __new__(cls, name, bases, dct):
if isinstance(dct.get("foo"), FunctionType):
dct["foo"] = staticmethod(dct["foo"])
return super().__new__(cls, name, bases, dct)
class B(metaclass=BMeta):
foo = a.foo(1)
bar = a.bar
https://codehs.com/sandbox/id/python-3-BaZXiA
Is it possible to write a decorator that acts upon a class's method and uses the class's attributes? For example, I would like to add a decorator to functions that will return an error if one of the class's attributes (which is set when the user calls the function) is False.
For example, my attempt (broken code since is_active can't access MyClass's methods):
def is_active(active):
if active == False:
raise Exception("ERROR: Class is inactive")
class MyClass():
def __init__(self, active):
self.active = active
#is_active
def foo(self, variable):
print("foo")
return variable
#is_active
def bar(self, variable):
print("bar")
return variable
where the expected behaviour is:
cls = MyClass(active=True)
cls.foo(42)
---> function prints "foo" and returns 42
cls = MyClass(active=False)
cls.foo(42)
---> function raises an exception as the active flag is False
The above is a dummy example and the actual use case is more complex, but hopefully this shows the problem I'm facing.
If the above is possible, my extra question is: is it possible to "hide"/delete the methods from the instantiated class based on this flag. For example, if the user instantiates the class with a active=False then when they're using iPython and press <tab>, they can only see the methods which are permitted to be used?
Thank you.
Decorators can be confusing. Note a function is passed as a parameter and the decorator expects that a function (or callable object) is returned. So you just need to return a different function. You have everything else you need since self is passed as the first argument to a class method. You just need to add a new function in your decorator that does what you want.
def is_active_method(func):
def new_func(*args, **kwargs):
self_arg = args[0] # First argument is the self
if not self_arg.active:
raise Exception("ERROR: Class is inactive")
return func(*args, **kwargs)
return new_func
class MyClass():
def __init__(self, active):
self.active = active
#is_active_method
def foo(self, variable):
print("foo")
return variable
#is_active_method
def bar(self, variable):
print("bar")
return variable
m = MyClass(True) # Prints foo from the method
m.foo(2)
m = MyClass(False) # Outputs the exception
m.foo(2)
I need a delegated class to delegate a #classmethod. Here's what I've tried:
class Foo(object):
def __init__(self, a):
self.a = a
#classmethod
def from_a(cls, a):
return cls(a)
class Bar(object):
def __init__(self, foo):
elf._foo = foo
def __getattribute__(self, name):
return getattr(self._foo, name)
But, of course this doesn't define how to look up attributes of Foo (not of an instance of Foo), so Bar.from_a(5) will raise an AttributeError. While it is of course possible to do this explicitly by defining a from_a method on Bar or to do this at instantiation by calling Bar(Foo.from_a(5)), I would rather do this implicitly. Ideas?
I started working on what I thought would be a simple approach for this using a metaclass, but it is actually fairly complex. What you should probably be doing here is having Bar inherit from Foo, but I'll show you what I came up with all the same:
import types
import functools
def make_delegating_type(delegatee):
class DelegatingType(type):
def __getattr__(self, name):
obj = getattr(delegatee, name)
if isinstance(obj, (types.FunctionType, types.MethodType)):
#functools.wraps(obj)
def wrapper(*args, **kwargs):
result = obj(*args, **kwargs)
if isinstance(result, delegatee):
return self(result)
return result
return wrapper
return obj
return DelegatingType
class Foo(object):
def __init__(self, a): self.a = a
#classmethod
def from_a(cls, a): return cls(a)
class Bar(object):
__metaclass__ = make_delegating_type(Foo)
def __init__(self, foo): self._foo = foo
def __getattr__(self, name): return getattr(self._foo, name)
Note that in 3.x you would use class Bar(object, metaclass=make_delegating_type(Foo) instead of the __metaclass__ = make_delegating_type(Foo) line at the top of the Bar class body.
Here is how this works. Your current version currently delegates attribute lookups on instances of Bar to an instance of Foo, this uses a metaclass so that attributes lookups on the class Bar are delegated to the class Foo as well. Unfortunately it is not as simple as just using a __getattr__ definition that returns getattr(delegatee, name), because if the attribute your a looking up is a factory function as in your example you need a version of that factory function that will return an instance of your delegating type. So for example Bar.from_a(5) should be the same as Bar(Foo.from_a(5)), and with the naive approach you would just get Foo.from_a(5). That is why there is all the logic detecting if the attribute is a function or method, and creating a wrapper that checks the return type of that function/method.
To reiterate, I do not recommend that you use this code! It is much more complicated then just defining from_a on Bar or having Bar inherit from Foo. But hopefully it will be a learning experience for you, as it was for me.
This question already has answers here:
Creating a singleton in Python
(38 answers)
Closed 4 years ago.
There seem to be many ways to define singletons in Python. Is there a consensus opinion on Stack Overflow?
I don't really see the need, as a module with functions (and not a class) would serve well as a singleton. All its variables would be bound to the module, which could not be instantiated repeatedly anyway.
If you do wish to use a class, there is no way of creating private classes or private constructors in Python, so you can't protect against multiple instantiations, other than just via convention in use of your API. I would still just put methods in a module, and consider the module as the singleton.
Here's my own implementation of singletons. All you have to do is decorate the class; to get the singleton, you then have to use the Instance method. Here's an example:
#Singleton
class Foo:
def __init__(self):
print 'Foo created'
f = Foo() # Error, this isn't how you get the instance of a singleton
f = Foo.instance() # Good. Being explicit is in line with the Python Zen
g = Foo.instance() # Returns already created instance
print f is g # True
And here's the code:
class Singleton:
"""
A non-thread-safe helper class to ease implementing singletons.
This should be used as a decorator -- not a metaclass -- to the
class that should be a singleton.
The decorated class can define one `__init__` function that
takes only the `self` argument. Also, the decorated class cannot be
inherited from. Other than that, there are no restrictions that apply
to the decorated class.
To get the singleton instance, use the `instance` method. Trying
to use `__call__` will result in a `TypeError` being raised.
"""
def __init__(self, decorated):
self._decorated = decorated
def instance(self):
"""
Returns the singleton instance. Upon its first call, it creates a
new instance of the decorated class and calls its `__init__` method.
On all subsequent calls, the already created instance is returned.
"""
try:
return self._instance
except AttributeError:
self._instance = self._decorated()
return self._instance
def __call__(self):
raise TypeError('Singletons must be accessed through `instance()`.')
def __instancecheck__(self, inst):
return isinstance(inst, self._decorated)
You can override the __new__ method like this:
class Singleton(object):
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(
cls, *args, **kwargs)
return cls._instance
if __name__ == '__main__':
s1 = Singleton()
s2 = Singleton()
if (id(s1) == id(s2)):
print "Same"
else:
print "Different"
A slightly different approach to implement the singleton in Python is the borg pattern by Alex Martelli (Google employee and Python genius).
class Borg:
__shared_state = {}
def __init__(self):
self.__dict__ = self.__shared_state
So instead of forcing all instances to have the same identity, they share state.
The module approach works well. If I absolutely need a singleton I prefer the Metaclass approach.
class Singleton(type):
def __init__(cls, name, bases, dict):
super(Singleton, cls).__init__(name, bases, dict)
cls.instance = None
def __call__(cls,*args,**kw):
if cls.instance is None:
cls.instance = super(Singleton, cls).__call__(*args, **kw)
return cls.instance
class MyClass(object):
__metaclass__ = Singleton
See this implementation from PEP318, implementing the singleton pattern with a decorator:
def singleton(cls):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance
#singleton
class MyClass:
...
The Python documentation does cover this:
class Singleton(object):
def __new__(cls, *args, **kwds):
it = cls.__dict__.get("__it__")
if it is not None:
return it
cls.__it__ = it = object.__new__(cls)
it.init(*args, **kwds)
return it
def init(self, *args, **kwds):
pass
I would probably rewrite it to look more like this:
class Singleton(object):
"""Use to create a singleton"""
def __new__(cls, *args, **kwds):
"""
>>> s = Singleton()
>>> p = Singleton()
>>> id(s) == id(p)
True
"""
it_id = "__it__"
# getattr will dip into base classes, so __dict__ must be used
it = cls.__dict__.get(it_id, None)
if it is not None:
return it
it = object.__new__(cls)
setattr(cls, it_id, it)
it.init(*args, **kwds)
return it
def init(self, *args, **kwds):
pass
class A(Singleton):
pass
class B(Singleton):
pass
class C(A):
pass
assert A() is A()
assert B() is B()
assert C() is C()
assert A() is not B()
assert C() is not B()
assert C() is not A()
It should be relatively clean to extend this:
class Bus(Singleton):
def init(self, label=None, *args, **kwds):
self.label = label
self.channels = [Channel("system"), Channel("app")]
...
As the accepted answer says, the most idiomatic way is to just use a module.
With that in mind, here's a proof of concept:
def singleton(cls):
obj = cls()
# Always return the same object
cls.__new__ = staticmethod(lambda cls: obj)
# Disable __init__
try:
del cls.__init__
except AttributeError:
pass
return cls
See the Python data model for more details on __new__.
Example:
#singleton
class Duck(object):
pass
if Duck() is Duck():
print "It works!"
else:
print "It doesn't work!"
Notes:
You have to use new-style classes (derive from object) for this.
The singleton is initialized when it is defined, rather than the first time it's used.
This is just a toy example. I've never actually used this in production code, and don't plan to.
I'm very unsure about this, but my project uses 'convention singletons' (not enforced singletons), that is, if I have a class called DataController, I define this in the same module:
_data_controller = None
def GetDataController():
global _data_controller
if _data_controller is None:
_data_controller = DataController()
return _data_controller
It is not elegant, since it's a full six lines. But all my singletons use this pattern, and it's at least very explicit (which is pythonic).
The one time I wrote a singleton in Python I used a class where all the member functions had the classmethod decorator.
class Foo:
x = 1
#classmethod
def increment(cls, y=1):
cls.x += y
Creating a singleton decorator (aka an annotation) is an elegant way if you want to decorate (annotate) classes going forward. Then you just put #singleton before your class definition.
def singleton(cls):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance
#singleton
class MyClass:
...
There are also some interesting articles on the Google Testing blog, discussing why singleton are/may be bad and are an anti-pattern:
Singletons are Pathological Liars
Where Have All the Singletons Gone?
Root Cause of Singletons
I think that forcing a class or an instance to be a singleton is overkill. Personally, I like to define a normal instantiable class, a semi-private reference, and a simple factory function.
class NothingSpecial:
pass
_the_one_and_only = None
def TheOneAndOnly():
global _the_one_and_only
if not _the_one_and_only:
_the_one_and_only = NothingSpecial()
return _the_one_and_only
Or if there is no issue with instantiating when the module is first imported:
class NothingSpecial:
pass
THE_ONE_AND_ONLY = NothingSpecial()
That way you can write tests against fresh instances without side effects, and there is no need for sprinkling the module with global statements, and if needed you can derive variants in the future.
The Singleton Pattern implemented with Python courtesy of ActiveState.
It looks like the trick is to put the class that's supposed to only have one instance inside of another class.
class Singleton(object[,...]):
staticVar1 = None
staticVar2 = None
def __init__(self):
if self.__class__.staticVar1==None :
# create class instance variable for instantiation of class
# assign class instance variable values to class static variables
else:
# assign class static variable values to class instance variables
class Singeltone(type):
instances = dict()
def __call__(cls, *args, **kwargs):
if cls.__name__ not in Singeltone.instances:
Singeltone.instances[cls.__name__] = type.__call__(cls, *args, **kwargs)
return Singeltone.instances[cls.__name__]
class Test(object):
__metaclass__ = Singeltone
inst0 = Test()
inst1 = Test()
print(id(inst1) == id(inst0))
OK, singleton could be good or evil, I know. This is my implementation, and I simply extend a classic approach to introduce a cache inside and produce many instances of a different type or, many instances of same type, but with different arguments.
I called it Singleton_group, because it groups similar instances together and prevent that an object of the same class, with same arguments, could be created:
# Peppelinux's cached singleton
class Singleton_group(object):
__instances_args_dict = {}
def __new__(cls, *args, **kwargs):
if not cls.__instances_args_dict.get((cls.__name__, args, str(kwargs))):
cls.__instances_args_dict[(cls.__name__, args, str(kwargs))] = super(Singleton_group, cls).__new__(cls, *args, **kwargs)
return cls.__instances_args_dict.get((cls.__name__, args, str(kwargs)))
# It's a dummy real world use example:
class test(Singleton_group):
def __init__(self, salute):
self.salute = salute
a = test('bye')
b = test('hi')
c = test('bye')
d = test('hi')
e = test('goodbye')
f = test('goodbye')
id(a)
3070148780L
id(b)
3070148908L
id(c)
3070148780L
b == d
True
b._Singleton_group__instances_args_dict
{('test', ('bye',), '{}'): <__main__.test object at 0xb6fec0ac>,
('test', ('goodbye',), '{}'): <__main__.test object at 0xb6fec32c>,
('test', ('hi',), '{}'): <__main__.test object at 0xb6fec12c>}
Every object carries the singleton cache... This could be evil, but it works great for some :)
My simple solution which is based on the default value of function parameters.
def getSystemContext(contextObjList=[]):
if len( contextObjList ) == 0:
contextObjList.append( Context() )
pass
return contextObjList[0]
class Context(object):
# Anything you want here
Being relatively new to Python I'm not sure what the most common idiom is, but the simplest thing I can think of is just using a module instead of a class. What would have been instance methods on your class become just functions in the module and any data just becomes variables in the module instead of members of the class. I suspect this is the pythonic approach to solving the type of problem that people use singletons for.
If you really want a singleton class, there's a reasonable implementation described on the first hit on Google for "Python singleton", specifically:
class Singleton:
__single = None
def __init__( self ):
if Singleton.__single:
raise Singleton.__single
Singleton.__single = self
That seems to do the trick.
Singleton's half brother
I completely agree with staale and I leave here a sample of creating a singleton half brother:
class void:pass
a = void();
a.__class__ = Singleton
a will report now as being of the same class as singleton even if it does not look like it. So singletons using complicated classes end up depending on we don't mess much with them.
Being so, we can have the same effect and use simpler things like a variable or a module. Still, if we want use classes for clarity and because in Python a class is an object, so we already have the object (not and instance, but it will do just like).
class Singleton:
def __new__(cls): raise AssertionError # Singletons can't have instances
There we have a nice assertion error if we try to create an instance, and we can store on derivations static members and make changes to them at runtime (I love Python). This object is as good as other about half brothers (you still can create them if you wish), however it will tend to run faster due to simplicity.
In cases where you don't want the metaclass-based solution above, and you don't like the simple function decorator-based approach (e.g. because in that case static methods on the singleton class won't work), this compromise works:
class singleton(object):
"""Singleton decorator."""
def __init__(self, cls):
self.__dict__['cls'] = cls
instances = {}
def __call__(self):
if self.cls not in self.instances:
self.instances[self.cls] = self.cls()
return self.instances[self.cls]
def __getattr__(self, attr):
return getattr(self.__dict__['cls'], attr)
def __setattr__(self, attr, value):
return setattr(self.__dict__['cls'], attr, value)