Object Creation using __new__ method - python

I'm trying to create a sample object to test the __new__ and __init__ method.
Here is my sample code. When I run this - I see "Its been created" msg and dont see the "Initialized" & "Deleted" msg.
class Test( object ):
def __new__(self):
print 'Its been Created'
def __init__(self):
print 'Its been Initialzed'
def __del__(self):
print 'Its been Deleted'
T = Test()

__new__ needs to return an instance of the class (see docs). What you're effectively doing here is returning the instance on NoneType (since functions with no explicit return value return None (and 'the' in this case because None is a special-case singleton in Python)), then having __init__ of that object called. The simplest way to fix this would be something like:
class Test(object):
def __new__(cls):
print 'Creating'
return super(Test, cls).__new__(cls)
def __init__(self):
print 'Intializing'
def __del__(self):
print 'Deleting'
This will cause Test.__new__() to return the result of Test's superclass' (object in this case) __new__ method as the newly created instance.
It may help you to understand what's going on if you try the following:
class A(object):
def __new__(cls):
print 'A.__new__'
return super(A, cls).__new__(cls)
def __init__(self):
print 'A.__init__'
def __del__(self):
print 'A.__del__'
class FakeA(object):
def __new__(cls):
print 'FakeA.__new__'
return A.__new__()
def __init__(self):
print 'FakeA.__init__'
def __del__(self):
print 'FakeA.__del__'
a = A()
fa = FakeA()
del a
del fa
However, it is important to note that __del__ is not guaranteed to be called on every instance every time.

Related

Why would calling the super class `__getattribute__` cause an infinite recursion?

clearly the following will result in an infinite loop:
class Klaus:
def __getattribute__(self, key):
return getattr(type(self), key)
However, I don't see why calling the super class __getattribute__ would:
class Parent:
def __init__(self):
print("begin __init__")
self._x = 3
print("end __init__")
def __getattribute__(self, attr_name):
superk = super(type(self), self)
boohl = superk.__getattribute__ == self.__getattribute__
print("with age comes wisdom", boohl)
return superk.__getattribute__(attr_name)
class Child(Parent):
def __getattribute__(self, attr_name):
superk = super(type(self), self)
boohl = superk.__getattribute__ == self.__getattribute__
print("this booger is green!", boohl)
return super(type(self), self).__getattribute__(attr_name)
obj = Child()
print("lambda")
print(obj._x)
print("anonymous")
Because type(self) is always Child. Even though you're in a method of Parent, self is still an instance of Child.
This is why when you use the long form of super you must always explicitly use the current class, rather than this. Of course, in Python 3 you can use super() without any parameters anyway.

How to inherit Base class with singleton in python

I have base class which is singleton, i need to inherit that in my another class but i get error message as
TypeError: Error when calling the metaclass bases
function() argument 1 must be code, not str
Can someone help with this.
Below is sample code.
def singleton(cls):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance
#singleton
class ClassOne(object):
def methodOne(self):
print "Method One"
def methodTwo(self):
print "Method Two"
class ClassTwo(ClassOne):
pass
You must make the singleton a class instead of a function for derivation to work. Here is an example that has been tested on both Python 2.7 and 3.5:
class singleton(object):
instances = {}
def __new__(cls, clz = None):
if clz is None:
# print ("Creating object for", cls)
if not cls.__name__ in singleton.instances:
singleton.instances[cls.__name__] = \
object.__new__(cls)
return singleton.instances[cls.__name__]
# print (cls.__name__, "creating", clz.__name__)
singleton.instances[clz.__name__] = clz()
singleton.first = clz
return type(clz.__name__, (singleton,), dict(clz.__dict__))
If you use this with your example classes:
#singleton
class ClassOne(object):
def methodOne(self):
print "Method One"
def methodTwo(self):
print "Method Two"
class ClassTwo(ClassOne):
pass
classes A and B will both be singletons
Beware, it is uncommon to inherit from a singleton class.

should the return value for `__enter__` method always be `self` in python

Shouldn't the return value for the __enter__ method be self always.
Python documentation says :
object.__enter__(self)
Enter the runtime context related to this
object. The with statement will bind this method’s return value to the
target(s) specified in the as clause of the statement, if any.
With this, to do anything practical, should't self be returned always from __enter__ method of a class as without it one would not be able to call other class methods on the context.
For example, in the following code, s.main() works fine but b1.main() errors out.
class a(object):
def __init__(self):
pass
def __enter__(self):
return self
def __exit__(self ,type, value, traceback):
return self
def main(self):
print " in a::main self %d " , id(self)
class b(object):
def __init__(self):
pass
def __enter__(self):
return "something else"
def __exit__(self ,type, value, traceback):
pass
def main(self):
print "in b::main !! self id " , id(self)
with a() as s:
s.main()
with b() as b1:
b1.main()
s = a()
s.main()
Not if it makes sense to use an attribute of the instance as the context manager:
class A:
def __init__(self, useful_obj):
self.useful_obj = useful_obj
def __enter__(self):
return self.useful_obj
def __exit__(self):
pass
with A(some_obj) as a:
# magic done implicitly by a.useful_obj
.
.
.
This situation can be seen in SqlAlchemy's code.
The code sample that you provided would work if you use any of the str methods, for example:
with b() as b1:
print b1.upper()
>> SOMETHING ELSE

Specifying an exit function for an abstract function

I need a way to call a function from an abstract method, i.e.
class A(object):
#abc.abstractmethod
def method1(self):
raise Exception("Unimplemented method")
def method2(self):
print "method1 finished"
class B(A):
def method1(self):
print "executing method1 from class B"
I need a way to automatically call method2 of class A, after the method1 has been executed (It should be done on the class A side - independently from inherited classes).
Is there a nice way of doing this?
You could use a metaclass, which wraps method1 at the time the class is created:
from functools import wraps
class MetaA(type):
def __new__(meta, name, bases, attr):
method1 = attr['method1']
if not getattr(method, '__isabstractmethod__'):
#wraps(method1)
def wrapper(self, *args, **kw):
res = method1(self, *args, **kw)
self.method2()
return res
attr['method1'] = wrapper
return super(MetaA, meta).__new__(meta, name, bases, attr)
class A(object):
__metaclass__ = MetaA
#abc.abstractmethod
def method1(self):
raise Exception("Unimplemented method")
def method2(self):
print "method1 finished"
This applies what is basically a decorator to a specific method whenever a (sub)class is created.
Another approach, somewhat hackish, is to intercept the method access, but would work. You'd implement a __getattribute__ hook on A that adds a wrapper:
from functools import wraps
class A(object):
#abc.abstractmethod
def method1(self):
raise Exception("Unimplemented method")
def method2(self):
print "method1 finished"
def __getattribute__(self, name):
obj = super(A, self).__getattribute__(name)
if name == 'method1':
#wraps(obj)
def wrapper(*args, **kw):
res = obj()
self.method2()
return res
return wrapper
return obj
Either approach results in:
>>> B().method1()
executing method1 from class B
method1 finished
By using the #functools.wraps() decorator the wrapper maintains several important attributes from the wrapped method, like its name and docstring.
This looks like a job for the Template method pattern, for example:
class A(object):
def method1(self):
# do something before
try:
self.method1_impl()
finally:
# do something after, for example:
self.method2()
#abc.abstractmethod
def method1_impl(self):
pass
def method2(self):
print "method1 finished"
class B(A):
def method1_impl(self):
print "executing method1 from class B"
While I'm not a proponent of this style (it tends to become hard to comprehend as the code grows and becomes more complex), this is occasionally used and has right to exist.
When this kind of situation happens, it can usually be solved by overriding "deeper" functionality.
Instead of having class B override method1, make it override method1_subfunction, and call both method1_subfunction and method2 from method1
class A(object):
def method1(self):
self.method1_subfunction()
self.method2()
#abc.abstractmethod
def method1_subfunction(self):
raise Exception("Unimplemented method")
def method2(self):
print "method1 finished"
class B(A):
def method1_subfunction(self):
print "executing method1 from class B"

Overriding inherited properties’ getters and setters in Python

I’m currently using the #property decorator to achieve “getters and setters” in a couple of my classes. I wish to be able to inherit these #property methods in a child class.
I have some Python code (specifically, I’m working in py3k) which looks vaguely like so:
class A:
#property
def attr(self):
try:
return self._attr
except AttributeError:
return ''
class B(A):
#property
def attr(self):
return A.attr # The bit that doesn't work.
#attr.setter
def attr(self, value):
self._attr = value
if __name__ == '__main__':
b = B()
print('Before set:', repr(b.attr))
b.attr = 'abc'
print(' After set:', repr(b.attr))
I have marked the part that doesn’t work with a comment. I want the base class’ attr getter to be returned. A.attr returns a property object (which is probably very close to what I need!).
Edit:
After receiving the answer below from Ned I thought up what I think is a more elegant solution to this problem.
class A:
#property
def attr(self):
try:
return self._attr
except AttributeError:
return ''
class B(A):
#A.attr.setter
def attr(self, value):
self._attr = value
if __name__ == '__main__':
b = B()
print('Before set:', repr(b.attr))
b.attr = 'abc'
print(' After set:', repr(b.attr))
The .setter decorator expects a property object which we can get using #A.attr. This means we do not have to declare the property again in the child class.
(This is the difference between working on a problem at the end of the day vs working on it at the beginning of the day!)
To override a setter in python 2 I did this:
class A(object):
def __init__(self):
self._attr = None
#property
def attr(self):
return self._attr
#attr.setter
def attr(self, value):
self._attr = value
class B(A):
#A.attr.setter
def attr(self, value):
# Do some crazy stuff with `value`
value = value[0:3]
A.attr.fset(self, value)
To understand where A.attr.fset came from see the documentation on the property class:
https://docs.python.org/2/library/functions.html#property
I think you want:
class B(A):
#property
def attr(self):
return super(B, self).attr
You mention wanting to return the parent class's getter, but you need to invoke the getter, not return it.

Categories

Resources