Monkey patch __del__ to new function - python

For specific debugging purposes I'd like to wrap the del function of an arbitrary object to perform extra tasks like write the last value of the object to a file.
Ideally I want to write
monkey(x)
and it should mean that the final value of x is printed when x is deleted
Now I figured that del is a class method. So the following is a start:
class Test:
def __str__(self):
return "Test"
def p(self):
print(str(self))
def monkey(x):
x.__class__.__del__=p
a=Test()
monkey(a)
del a
However if I want to monkey specific objects only I suppose I need to dynamically rewrite their class to a new one?! Moreover I need to do this anyway, since I cannot access del of built-in types?
Anyone knows how to implement that?

While special 'double underscore' methods like __del__, __str__, __repr__, etc. can be monkey-patched on the instance level, they'll just be ignored, unless they are called directly (e.g., if you take Omnifarious's answer: del a won't print a thing, but a.__del__() would).
If you still want to monkey patch a single instance a of class A at runtime, the solution is to dynamically create a class A1 which is derived from A, and then change a's class to the newly-created A1. Yes, this is possible, and a will behave as if nothing has changed - except that now it includes your monkey patched method.
Here's a solution based on a generic function I wrote for another question:
Python method resolution mystery
def override(p, methods):
oldType = type(p)
newType = type(oldType.__name__ + "_Override", (oldType,), methods)
p.__class__ = newType
class Test(object):
def __str__(self):
return "Test"
def p(self):
print(str(self))
def monkey(x):
override(x, {"__del__": p})
a=Test()
b=Test()
monkey(a)
print "Deleting a:"
del a
print "Deleting b:"
del b

del a deletes the name 'a' from the namespace, but not the object referenced by that name. See this:
>>> x = 7
>>> y = x
>>> del x
>>> print y
7
Also, some_object.__del__ is not guaranteed to be called at all.
Also, I already answered your question here (in german).

You can also inherit from some base class and override the __del__ method (then only thing you would need would be to override class when constructing an object).
Or you can use super built-in method.

Edit: This won't actually work, and I'm leaving it here largely as a warning to others.
You can monkey patch an individual object. self will not get passed to functions that you monkey patch in this way, but that's easily remedied with functools.partial.
Example:
def monkey_class(x):
x.__class__.__del__ = p
def monkey_object(x):
x.__del__ = functools.partial(p, x)

Related

Why doesn't Python allow referencing a class inside its definition?

Python (3 and 2) doesn't allow you to reference a class inside its body (except in methods):
class A:
static_attribute = A()
This raises a NameError in the second line because 'A' is not defined, while this
class A:
def method(self):
return A('argument')
works fine.
In other languages, for example Java, the former is no problem and it is advantageous in many situations, like implementing singletons.
Why isn't this possible in Python? What are the reasons for this decision?
EDIT:
I edited my other question so it asks only for ways to "circumvent" this restriction, while this questions asks for its motivation / technical details.
Python is a dynamically typed language, and executes statements as you import the module. There is no compiled definition of a class object, the object is created by executing the class statement.
Python essentially executes the class body like a function, taking the resulting local namespace to form the body. Thus the following code:
class Foo(object):
bar = baz
translates roughly to:
def _Foo_body():
bar = baz
return locals()
Foo = type('Foo', (object,), _Foo_body())
As a result, the name for the class is not assigned to until the class statement has completed executing. You can't use the name inside the class statement until that statement has completed, in the same way that you can't use a function until the def statement has completed defining it.
This does mean you can dynamically create classes on the fly:
def class_with_base(base_class):
class Foo(base_class):
pass
return Foo
You can store those classes in a list:
classes = [class_with_base(base) for base in list_of_bases]
Now you have a list of classes with no global names referring to them anywhere. Without a global name, I can't rely on such a name existing in a method either; return Foo won't work as there is no Foo global for that to refer to.
Next, Python supports a concept called a metaclass, which produces classes just like a class produces instances. The type() function above is the default metaclass, but you are free to supply your own for a class. A metaclass is free to produce whatever it likes really, even things that are bit classes! As such Python cannot, up front, know what kind of object a class statement will produce and can't make assumptions about what it'll end up binding the name used to. See What is a metaclass in Python?
All this is not something you can do in a statically typed language like Java.
A class statement is executed just like any other statement. Your first example is (roughly) equivalent to
a = A()
A = type('A', (), {'static_attribute': a})
The first line obviously raises a NameError, because A isn't yet bound to anything.
In your second example, A isn't referenced until method is actually called, by which time A does refer to the class.
Essentially, a class does not exist until its entire definition is compiled in its entirety. This is similar to end blocks that are explicitly written in other languages, and Python utilizes implicit end blocks which are determined by indentation.
The other answers are great at explaining why you can't reference the class by name within the class, but you can use class methods to access the class.
The #classmethod decorator annotes a method that will be passed the class type, instead of the usual class instance (self). This is similar to Java's static method (there's also a #staticmethod decorator, which is a little different).
For a singleton, you can access a class instance to store an object instance (Attributes defined at the class level are the fields defined as static in a Java class):
class A(object):
instance = None
#classmethod
def get_singleton(cls):
if cls.instance is None:
print "Creating new instance"
cls.instance = cls()
return cls.instance
>>> a1 = A.get_singleton()
Creating new instance
>>> a2 = A.get_singleton()
>>> print a1 is a2
True
You can also use class methods to make java-style "static" methods:
class Name(object):
def __init__(self, name):
self.name = name
#classmethod
def make_as_victoria(cls):
return cls("Victoria")
#classmethod
def make_as_stephen(cls):
return cls("Stephen")
>>> victoria = Name.make_as_victoria()
>>> stephen = Name.make_as_stephen()
>>> print victoria.name
Victoria
>>> print stephen.name
Stephen
The answer is "just because".
It has nothing to do with the type system of Python, or it being dynamic. It has to do with the order in which a newly introduced type is initialized.
Some months ago I developed an object system for the language TXR, in which this works:
1> (defstruct foo nil (:static bar (new foo)))
#
2> (new foo)
#S(foo)
3> *2.bar
#S(foo)
Here, bar is a static slot ("class variable") in foo. It is initialized by an expression which constructs a foo.
Why that works can be understood from the function-based API for the instantiation of a new type, where the static class initialization is performed by a function which is passed in. The defstruct macro compiles a call to make-struct-type in which the (new foo) expression ends up in the body of the anonymous function that is passed for the static-initfun argument. This function is called after the type is registered under the foo symbol already.
We could easily patch the C implementation of make_struct_type so that this breaks. The last few lines of that function are:
sethash(struct_type_hash, name, stype);
if (super) {
mpush(stype, mkloc(su->dvtypes, super));
memcpy(st->stslot, su->stslot, sizeof (val) * su->nstslots);
}
call_stinitfun_chain(st, stype);
return stype;
}
The call_stinifun_chain does the initialization which ends up evaluating (new foo) and storing it in the bar static slot, and the sethash call is what registers the type under its name.
If we simply reverse the order in which these functions are called, the language and type system will still be the same, and almost everything will work as before. Yet, the (:static bar (new foo)) slot specifier will fail.
I put the calls in that order because I wanted the language-controlled aspects of the type to be as complete as possible before exposing it to the user-definable initializations.
I can't think of any reason for foo not to be known at the time when that struct type is being initialized, let alone a good reason. It is legitimate for static construction to create an instance. For example, we could use it to create a "singleton".
This looks like a bug in Python.

Using self in python, outside of a class

I am a bit unsure how to use self outside of a class. A lot of built in methods in python use self as a parameter and there is no need for you to declare the class; For example, you can use the string.upper() command to capitalize each letter without needing to tell python which class to use. In case I'm not explaining myself well, I have included what my code looks like below.
def ispalendrome(self): return self == self[::-1]
largestProd = 999**2
largest5Palendromes = []
while len(largest5Palendromes) <= 5:
if str(largestProd).ispalendrome(): largest5Palendromes.append(largestProd)
largestProd -= 1
print largest5Palendromes
Note: I understand there are other ways of accomplishing this task, but I would like to know if this is possible. TYVM.
using https://github.com/clarete/forbiddenfruit
from forbiddenfruit import curse
def ispalendrome(self): #note that self is really just a variable name ... it doent have to be named self
return self == self[::-1]
curse(str, "ispalendrome",ispalendrome)
"hello".ispalendrome()
note that just because you can does not mean its a good idea
alternatively it is much better to just do
def ispalendrome(a_string):
return a_string == a_string[::-1]
ispalendrome("hello")
It feels like you want to monkey patch a method onto this. If so, then welcome to the dark side young one. Let us begin the cursed ritual. In essence you want to monkey patch. All we need is a little monkey blood. Just kidding. We need type.MethodType. But note, that you cannot monkey patch stdlib types:
>>> from types import MethodType
>>> def palindrome(self): return self == self[::-1]
...
>>> str.palindrome = MethodType(palindrome, str)
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: can't set attributes of built-in/extension type 'str'
But that won't stop you from causing havoc in other classes:
>>> class String(object):
... def __init__(self, done):
... self.done = done
...
...
...
>>> s = String("stanley yelnats")
>>> def palindrome(self): return self.done[::-1]
>>> s.palindrome = MethodType(palindrome, s)
>>> s.palindrome()
'stanley yelnats'
You see how easy that was? But we're just getting started. This is just a mere instance lets kill a class now shall we? The next part will get you laughing maniacally:
>>> from types import DynamicClassAttribute
>>> class String(object):
... def __init__(self, done):
... self.done = done
...
...
...
>>> s = String("cheese")
>>> def palindrome(self): return self.done[::-1];
...
>>> String.palindrome = DynamicClassAttribute(palindrome)
>>> s.palindrome
'eseehc'
After this, if you do not feel evil. Then you must come over to my evil lair, where I shall show you more evil tricks and share cookies.
Self has no special meaning - it is just a variable name. Its use in classes is merely conventional (so it may be confusing to use it elsewhere).
You can, however, set the properties of a class after-the-fact, and these could be class methods or instance methods (the latter with "self" by convention). This will NOT work with the built-in classes like str, though [edit: so you'd have to "curse" or subclass, see other answer]
In
def ispalendrome(self)
there's no need to name the parameter self (indeed, it's a bit misleading), as this isn't an instance method. I would call it s (for string):
def is_palindrome(s):
What you may be referring to is the use of bound methods on the class, where:
an_instance = TheClass()
an_instance.instance_method() # self is passed implicitly
is equivalent to:
an_instance = TheClass()
TheClass.instance_method(an_instance) # self is passed explicitly
In this particular case, for example:
>>> "foo".upper()
'FOO'
>>> str.upper("foo")
'FOO'
In Python the first argument to a class method is the object instance itself, by convention it is called self. You should prevent using self for other purposes.
To explain it more detailed:
If you have a class
class A(object):
def __init__(self):
self.b = 1
and you make an instance of it:
a = A()
this calls the init method and the parameter self if filled with a fresh object. Then self.b = 1 is called and add the attribute b to the new object. This object is then going to become knows as a.
"self" is the name of the first parameter to a function - like any parameter, it has no meaning outside of that function. What it corresponds to is the object on which that function is called.

Python 3: Calling a Function from a class, self

I am trying to learn about classes, can someone explain to me why this code is not working. I thought when calling a function from a class, "self" is automatically ommitted, but the interpreter tells me that argument "a" is missing (he thinks self = 10).
#! coding=utf-8
class test:
def __init__(self):
"do something here"
def do(self,a):
return a**2
d = test.do
print(d(10))
Instantiate the class first:
d = test().do
print(d(10)) # prints 100
test.do is an unbound method, test().do is bound. The difference is explained in this thread: Class method differences in Python: bound, unbound and static.
You have to instantiate the class first:
d = test()
then you can call a method:
print(d.do(10))
if you want to use method statically you have to declare it in python
#! coding=utf-8
class test:
def __init__(self):
"do something here"
#staticmethod
def do(a):
return a**2
d = test.do
print(d(10)) #and that's work
Since you haven't instantiated the class (a fancy term for created) you can't be assigning methods to any random variable. Like already said, you must create the object first, whilst making sure the method you call is a part of the class you called or connected to the class in some way (such as creating another class and then communicating that class with the current class). So you should first type d=test() followed by d.do().
Also, remember that in your declaration of the method you crated a parameter so what you done was wrong in itself anyway, because when you declared the do function, you should have put within the brackets the number you wanted to send to the method to calculate its square. So you type test.do(10) and then the 10 is sent by the self reference to the method to be done whatever it is you told it to do.
One more thing: although it isn't a huge deal, it helps if all of your class names begin with a capital letter, as this is usually the 'pythonic' way to do things, and it also makes your code much easier to read, because when you first called the class, somebody could easily mistaken it for an ordinary function
class test:
def __init__(self):
"do something here"
def do(self,a):
return a**2
def __call__(self,a):
return self.do(a)
a = test
test.do(a,10)
#or
a = test().do
a(10)
#or
a = test()
test.do(a,10)
#or
a = test()
print(a(10))

How is this called and how can be done ( `function_name.decorator` )?

Really sorry for the extremely stupid title, but if I know what it is, I wouldn't write here (:
def some_decorator( func ):
# ..
class A:
#some_decorator
def func():
pass
#func.some_decorator # this one here - func.some_decorator ?
def func():
pass
some_decorator decorates func - that's OK. But what is func.some_decorator and how some_decorator becomes a member ( or something else ? ) of func?
P.S. I'm 90% sure, that there's such question here (as this seems something basic), but I don't know how to search it. If there's a exact duplicate, I'll delete this question.
Note : It's not typo, nor accident, that both member functions are named func. The decorator is for overloading: the question is related to Decorating method (class methods overloading)
Remember that the function definition with decorator is equivalent to this:
def func():
pass
func = some_decorator(func)
So in the following lines, func doesn't refer to the function you defined but to what the decorator turned it into. Also note that decorators can return any object, not just functions. So some_decorator returns an object with a method (it's unfortunate that the names some_decorator and func are reused in the example - it's confusing, but doesn't change anything about the concept) that is itself a decorator. As the expression after the # is evaluated first, you still have a reference to the first decorator's method after you defined another plain function func. That decorator is applied to this new function. The full example is then equivalent to this:
class A:
def func():
pass
func = some_decorator(func)
_decorator = func.some_decorator
def func():
pass
func = _decorator(func)
One way to clarify this is to demonstrate it with a concrete example that behaves like this, the builtin property descriptor:
class C(object):
#property
def x(self):
"This is a property object, not a function"
return self._x
#x.setter
def x(self, val):
self._x = val
>>> c = C()
>>> c.x = 1
>>> c.x
1
>>> C.x
<property object at 0x2396100>
>>> C.x.__doc__
'This is a property object, not a function'
>>> C.x.getter.__doc__
'Descriptor to change the getter on a property.'
>>> C.x.setter.__doc__
'Descriptor to change the setter on a property.'
>>> C.x.deleter.__doc__
'Descriptor to change the deleter on a property.'
The first invocation of property (as a decorator) means that x is not a function - it is a property descriptor. A feature of properties is that they allow you to initially define just the fget method, and then provide fset and fdel later by using the property.setter and property.deleter decorators (although since each of these creates a new property object, you do need to make sure to use the same name each time).
Something similar will usually be the case whenever you see code using this kind of pattern. Ideally, the naming of the decorators involved will make it reasonably clear what is going on (e.g. most people seem to grasp the idiom for defining property attributes reasonably easily).

Setting a lambda function as a property

Consider these two classes:
class Test(int):
difference = property(lambda self: self.__sub__)
class Test2(int):
difference=lambda self: self.__sub__
Is there any difference between these two classes? New: If so, what is the purpose of using the property to store a lambda function that returns another function?
Update: Changed the question to what I should have asked in the first place. Sorry. Even though I can now know the solution from the answers, it would be unfair for me to do a self answer in these circumstances. (without leaving the answer for a few days at least).
Update 2: Sorry, I wasn't clear enough again. The question was about the particular construction, not properties in general.
For Test1, you could use .difference - for Test2, you'd need to use .difference() instead.
As for why you might use it, a potential use would be to replace something that was previously directly stored as a property with a dynamic calculation instead.
For instance, if you used to store property obj.a, but then you expanded your implementation so that it knew instead properties obj.b and obj.c that could be used to calculate a, but could also be used to calculate different things. If you still wanted to provide backwards-compat with things that used the previous object form, you could implement obj.a as a property() that calculated a based on b and c and it'd behave to those older code fragments as it previously did, with no other code modification needed.
Edit: Ah, I see. You are asking why anybody would do exactly the code above. It's not, in fact a question about why to make a lambda or a property at all, it's not a question of the differences between the two examples, and not even why you want to make a property out of a lambda.
Your question is "Why would anybody make a property of a lambda that just returns self.__sub__".
And the answer is: One wouldn't.
Let's assume somebody wants to do this:
>>> foo = MyInt(8)
>>> print foo.difference(7)
1
So he tries to accomplish it by this class:
class MyInt(int):
def difference(self, i):
return self - i
But that's two lines, and since he is a Ruby programmer and believes that good code is code that has few lines of code, he changes it to:
class MyInt(int):
difference = int.__sub__
To save one line of code. But apparently, things are still too easy. He learned in Ruby that a problem is not properly solved unless you use anonymous code blocks, so he will try to use Pythons nearest equivalent, lambdas, for absolutely no reason:
class MyInt(int):
difference=lambda self, i: self - i
All these works. But things are still WAY to uncomplicated, so instead he decides to make things more complex, by not doing the calculation, but returning the sub method:
class MyInt(int):
difference=lambda self: self.__sub__
Ah, but that doesn't work, because he needs to call difference to get the sub-method:
>>> foo = MyInt(8)
>>> print foo.difference()(7)
1
So he makes it a property:
class MyInt(int):
difference=property(lambda self: self.__sub__)
There. Now he has found the maximum complexity to solve a non-problem.
But normal people wouldn't do any of these, but do:
>>> foo = 8
>>> print foo - 7
1
People have given there opinion without analyzing it, it can be better solved by python itself, below is the code to check the difference
import difflib
from pprint import pprint
s1 = """
class Test(int):
difference=property(lambda self: self.__sub__)
"""
s2 = """
class Test(int):
difference=lambda self: self.__sub__
"""
d = difflib.Differ()
print "and the difference is..."
for c in d.compare(s1, s2):
if c[0] in '+-': print c[1:],
and as expected it says
and the difference is...
p r o p e r t y ( )
Yes, in one case difference is a property. If you are asking what a property is, you can see it as a method that gets automatically called.
Yes, in one case difference is a property
Purpose of property can be
1.
To provide get/set hooks while accessing an attribute
e.g. if you used to have class with attribute a, later on you want to do something else when it is set, you can convert that attribute to property without affecting the interface or how users use your class. So in the example below class A and B are exactly same for a user but internally in B you can do many things in get/setX
class A(object):
def __init__(self):
self.x = 0
a = A()
a.x = 1
class B(object):
def __init__(self):
self.x = 0
def getX(self): return self._x
def setX(self, x): self._x = x
x = property(getX, setX)
b = B()
B.x = 1
2.
As implied in 1, property is a better alternative to get/set calls, so instead of getX, setX user uses less verbose self.x and self.x = 1, though personally I never make a property just for getting or setting a attribute, if need arises it can be done later on as shown in #1/
as far as difference in concerned, property provide you with get/set/del for an atribute, but in the example you have given a method(lambda or proper function) can only be used to do one of get/set or del, so you will need three such lambdas differenceSet, differenceGet, differenceDel

Categories