def f(obj):
print('attr =', obj.attr)
class Foo:
attr = 100
attr_val = f
x = Foo()
print(x.attr)
x.attr_val()
Output:
100
attr = 100
I got this code from real python but I don't understand how x is pass into function f.
Can someone explain that to me, thanks.
x is a class object when you are doing x.attr_val() it automatically takes itself and provides it as a first argument to the function (often arguments like this are named self).
attr_val is what is called an instance method. When your Foo class calls it, it passes the object as first argument automatically, effectively running: f(x)
If you were using a custom __init__ method, the standard practice would be to pass the self variable to indicate this self-reference.
Thus, a more verbose variant would be:
def f(obj):
print('attr =', obj.attr)
class Foo:
def __init__(self):
self.attr = 100
def attr_val(self):
f(self) # or "return f(self)"
x = Foo()
x.attr_val()
# attr = 100
Related
I was trying to store reference to unbound method and noticed that it is being automatically bound. See example below. Is there more elegant way to store unbound method in the class without binding it?
def unbound_method():
print("YEAH!")
class A:
bound_method = unbound_method
unbound_methods = [unbound_method]
a = A()
a.unbound_methods[0]() # succeeds
a.bound_method() # fails
# TypeError: unbound_method() takes 0 positional arguments but 1 was given
This is not a standard "do you know about #staticmethod?" question.
What I'm trying to achieve is provide a way for children of the class provide another handler or certain situations. I do not control the unbound_method itself, it is provided from some library.
def unbound_method_a():
print("YEAH!")
def unbound_method_b():
print("WAY MORE YEAH!")
class A:
bound_method = unbound_method_a
class B(A):
bound_method = unbound_method_b
a = A()
a.bound_method() #fails
# print("YEAH!")
b = B()
b.bound_method() #fails
# print("WAY MORE YEAH!")
It can be achieved by wrapping the unbound method some dummy object like array, or in a bound method, just to drop self reference like this:
def unbound_method_a():
print("YEAH!")
def unbound_method_b():
print("WAY MORE YEAH!")
class A:
def call_unbound_method(self):
return unbound_method_a()
class B(A):
def call_unbound_method(self):
return unbound_method_b()
a = A()
a.call_unbound_method()
# print("YEAH!")
b = B()
b.call_unbound_method()
# print("WAY MORE YEAH!")
Not as far as I know. Would it be so bad if you just replace
a.bound_method()
with
A.bound_method()
?
I can't think of a situation in which the first one can't be replaced by the second one.
In python 3.4 I have a member object through composition.
I would like to override one of it's member functions.
def class Foo:
def __init__(self, value):
self.value = value
def member_obj.baz(baz_self, arg):
print("my new actions on {}".format(arg))
Foo.member_obj.baz(arg) #the original function
foo_inst = Foo(2)
bar = Bar(*bar_parameters) #from a third party module
setattr(foo_inst, "member_obj", bar) #it did not "stick" when I did foo_inst.member_obj = bar
foo_inst.member_obj.baz("some argument")
It does not make sense to inherit from the Bar class.
I also only want this different behaviour to occur if the object is inside Foo. I use Bar in many other places and would like to retain the same way of calling the method. I.e. I would like to avoid wrapping it in Foo.baz.
Is it even possible to do something like the def member_obj.baz and is it a good idea?
It would be similar to this: https://softwareengineering.stackexchange.com/questions/150973/what-are-the-alternatives-to-overriding-a-method-when-using-composition-instea
Are you trying to do something like this?
class B():
def __init__(self):
self.x = None
def fun(self):
print("Assigning value to attribute of object of class B.\n")
self.x = "Value of B object's attribute"
class A():
def __init__(self):
self.value = B()
def fun(self):
print("Screw this, I'll do something else this time!\n")
self.value.x = 13
def override(self):
# Edit: you can assign any identifier (that is not reserved) to
# any type of object or method AND the "fun" ("really self.fun")
# above is visible from here, since we passed "self" as an
# argument
self.value.fun = self.fun
myObj = B()
myOtherObj = A()
myOtherObj.override()
myObj.fun()
myOtherObj.value.fun()
Say I have a class Foo and I do foo = Foo(). I want some kind of "method namespace" foo.bar that is not shared across Foo instances, to which I dynamically can add methods that operate on foo:
def method(self, someValue):
self.value = someValue + 10
foo.bar.m = method
foo.bar.m(20)
And then I want to find that foo.value is 30.
Any way to accomplish this?
Is this what you're looking for?
import types
class Namespace(object):
pass
class Foo(object):
def __init__(self, value):
self.value = value
self.bar = Namespace()
def function(self, new_value):
self.value = new_value
a = Foo(1)
b = Foo(2)
b.bar.function = types.MethodType(function, b, Foo)
b.bar.function(6)
print a.value # prints 1
print b.value # prints 6
The trick is using the types module to convert the test function into a method that can be bound to an instance of the object.
When I run this line: b.bar.function = types.MethodType(function, b, Foo), I am essentially telling Python to create a new method that binds function to the b instance of Foo. I can then take this method and store it inside any arbitrary location.
Since the method is permanently bound to the b instance of Foo, self will always refer to b regardless of which object the method is actually assigned to.
I would like to wrap a number of class methods in Python with the same wrapper.
Conceptually it would look something like this in the simplest scenario:
x = 0 # some arbitrary context
class Base(object):
def a(self):
print "a x: %s" % x
def b(self):
print "b x: %s" % x
class MixinWithX(Base):
"""Wrap"""
def a(self):
global x
x = 1
super(MixinWithX, self).a()
x = 0
def b(self):
global x
x = 1
super(MixinWithX, self).a()
x = 0
Of course, when there are more methods than a and b, this becomes a mess. It seems like there ought to be something simpler. Obviously x could be modified in a decorator but one still ends up having a long list of garbage, which instead of the above looks like:
from functools import wraps
def withx(f):
#wraps(f) # good practice
def wrapped(*args, **kwargs):
global x
x = 1
f(*args, **kwargs)
x = 0
return wrapped
class MixinWithX(Base):
"""Wrap"""
#withx
def a(self):
super(MixinWithX, self).a()
#withx
def b(self):
super(MixinWithX, self).b()
I thought about using __getattr__ in the mixin, but of course since methods such as a and b are already defined this is never called.
I also thought about using __getattribute__ but it returns the attribute, not wrapping the call. I suppose __getattribute__ could return a closure (example below) but I am not sure how sound a design that is. Here is an example:
class MixinWithX(Base):
# a list of the methods of our parent class (Base) that are wrapped
wrapped = ['a', 'b']
# application of the wrapper around the methods specified
def __getattribute__(self, name):
original = object.__getattribute__(self, name)
if name in wrapped:
def wrapped(self, *args, **kwargs):
global x
x = 1 # in this example, a context manager would be handy.
ret = original(*args, **kwargs)
x = 0
return ret
return wrapped
return original
It has occurred to me that there may be something built into Python that may alleviate the need to manually reproduce every method of the parent class that is to be wrapped. Or maybe a closure in __getattribute__ is the proper way to do this. I would be grateful for thoughts.
Here's my attempt, which allows for a more terse syntax...
x = 0 # some arbitrary context
# Define a simple function to return a wrapped class
def wrap_class(base, towrap):
class ClassWrapper(base):
def __getattribute__(self, name):
original = base.__getattribute__(self, name)
if name in towrap:
def func_wrapper(*args, **kwargs):
global x
x = 1
try:
return original(*args, **kwargs)
finally:
x = 0
return func_wrapper
return original
return ClassWrapper
# Our existing base class
class Base(object):
def a(self):
print "a x: %s" % x
def b(self):
print "b x: %s" % x
# Create a wrapped class in one line, without needing to define a new class
# for each class you want to wrap.
Wrapped = wrap_class(Base, ('a',))
# Now use it
m = Wrapped()
m.a()
m.b()
# ...or do it in one line...
m = wrap_class(Base, ('a',))()
...which outputs...
a x: 1
b x: 0
You can do this using decorators and inspect:
from functools import wraps
import inspect
def withx(f):
#wraps(f)
def wrapped(*args, **kwargs):
print "decorator"
x = 1
f(*args, **kwargs)
x = 0
return wrapped
class MyDecoratingBaseClass(object):
def __init__(self, *args, **kwargs):
for member in inspect.getmembers(self, predicate=inspect.ismethod):
if member[0] in self.wrapped_methods:
setattr(self, member[0], withx(member[1]))
class MyDecoratedSubClass(MyDecoratingBaseClass):
wrapped_methods = ['a', 'b']
def a(self):
print 'a'
def b(self):
print 'b'
def c(self):
print 'c'
if __name__ == '__main__':
my_instance = MyDecoratedSubClass()
my_instance.a()
my_instance.b()
my_instance.c()
Output:
decorator
a
decorator
b
c
There are two general directions I can think of which are useful in your case.
One is using a class decorator. Write a function which takes a class, and returns a class with the same set of methods, decorated (either by creating a new class by calling type(...), or by changing the input class in place).
EDIT: (the actual wrapping/inspecting code I had in mind is similar to
what #girasquid has in his answer, but connecting is done using decoration instead of mixin/inheritance, which I think is more flexible an robust.)
Which brings me to the second option, which is to use a metaclass, which may be cleaner (yet trickier if you're not used to working with metaclasses). If you don't have access to the definition of the original class, or don't want to change the original definition, you can subclass the original class, setting the metaclass on the derived.
There is a solution, and it's called a decorator. Google "python decorators" for lots of information.
The basic concept is that a decorator is a function which takes a function as a parameter, and returns a function:
def decorate_with_x(f)
def inner(self):
self.x = 1 #you must always use self to refer to member variables, even if you're not decorating
f(self)
self.x = 0
return inner
class Foo(object):
#decorate_with_x # #-syntax passes the function defined on next line
# to the function named s.t. it is equivalent to
# foo_func = decorate_with_x(foo_func)
def foo_func(self):
pass
I would like to create a class whose f method depends on the "mode" the object of the class has been created.
The code below doesn't work but hope it gets you an idea of what I am trying to do. My idea is to have a dictionary in which I define the settings for each mode (in this case the function or method to assign to self.f, so that rather than using many if elif statements
in the init function I just assign the correct values using the dictionary.
class A(object):
_methods_dict={
'a':A.f1,
'b':A.f2
}
def __init__(self,mode = 'a'):
self.f = _methods_dict[mode]
def f1(self,x):
return x
def f2(self,x):
return x**2
I can't figure why this does not work, how would you fix it?
Also are there better (and more pythonic) approaches to get the same kind of functionalities?
Store the name of the two functions, then use getattr() to retrieve the bound method in __init__:
class A(object):
_methods_dict = {
'a': 'f1',
'b': 'f2'
}
def __init__(self, mode='a'):
self.f = getattr(self, self._methods_dict[mode])
def f1(self, x):
return x
def f2(self, x):
return x ** 2
Alternatively, just proxy the method:
class A(object):
_methods_dict = {
'a': 'f1',
'b': 'f2'
}
def __init__(self,mode = 'a'):
self._mode = mode
#property
def f(self):
return getattr(self, self._methods_dict[self._mode])
def f1(self, x):
return x
def f2(self, x):
return x ** 2
The f property just returns the correct bound method for the current mode. Using a property simplifies call signature handling, and gives users the actual method to introspect if they so wish.
Either method has the same end-result:
>>> a1 = A()
>>> a2 = A('b')
>>> a1.f(10)
10
>>> a2.f(10)
100
The difference lies in what is stored in the instance, the first method stores bound methods:
>>> vars(a1)
{'f': <bound method A.f1 of <__main__.A object at 0x10aa1ec50>>}
>>> vars(a2)
{'f': <bound method A.f2 of <__main__.A object at 0x10aa1ed50>>}
versus the method in the other:
>>> vars(a1)
{'_mode': 'a'}
>>> vars(a2)
{'_mode': 'b'}
That may not seem much of a difference, but the latter method creates instances that can be pickled and deep-copied without problems.
You could just make two separate classes:
class Base(object):
# place here all attributes shared in common among the Modes
pass
class ModeA(Base):
def f(self, x):
return x
class ModeB(Base):
def f(self, x):
return x**2
def make_mode(mode, *args, **kwargs):
mode_dict = {'a':ModeA, 'b':ModeB}
return mode_dict[mode](*args, **kwargs)
a = make_mode('a')
print(a.f(10))
# 10
b = make_mode('b')
print(b.f(10))
# 100
To answer your first question ("why this does not work"): the class object "A" is only created and bound to the module name "A" after the whole class statement (yes, "class" is an executable statement) block has ended, so you cannot refer to neither the name or the class object itself within this block.