Access class when used as class-level variable in Python - 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

Related

How do I get the class which the function belongs to? [duplicate]

How can I get the class that defined a method in Python?
I'd want the following example to print "__main__.FooClass":
class FooClass:
def foo_method(self):
print "foo"
class BarClass(FooClass):
pass
bar = BarClass()
print get_class_that_defined_method(bar.foo_method)
import inspect
def get_class_that_defined_method(meth):
for cls in inspect.getmro(meth.im_class):
if meth.__name__ in cls.__dict__:
return cls
return None
I don't know why no one has ever brought this up or why the top answer has 50 upvotes when it is slow as hell, but you can also do the following:
def get_class_that_defined_method(meth):
return meth.im_class.__name__
For python 3 I believe this changed and you'll need to look into .__qualname__.
In Python 3, if you need the actual class object you can do:
import sys
f = Foo.my_function
vars(sys.modules[f.__module__])[f.__qualname__.split('.')[0]] # Gets Foo object
If the function could belong to a nested class you would need to iterate as follows:
f = Foo.Bar.my_function
vals = vars(sys.modules[f.__module__])
for attr in f.__qualname__.split('.')[:-1]:
vals = vals[attr]
# vals is now the class Foo.Bar
Thanks Sr2222 for pointing out I was missing the point...
Here's the corrected approach which is just like Alex's but does not require to import anything. I don't think it's an improvement though, unless there's a huge hierarchy of inherited classes as this approach stops as soon as the defining class is found, instead of returning the whole inheritance as getmro does. As said, this is a very unlikely scenario.
def get_class_that_defined_method(method):
method_name = method.__name__
if method.__self__:
classes = [method.__self__.__class__]
else:
#unbound method
classes = [method.im_class]
while classes:
c = classes.pop()
if method_name in c.__dict__:
return c
else:
classes = list(c.__bases__) + classes
return None
And the Example:
>>> class A(object):
... def test(self): pass
>>> class B(A): pass
>>> class C(B): pass
>>> class D(A):
... def test(self): print 1
>>> class E(D,C): pass
>>> get_class_that_defined_method(A().test)
<class '__main__.A'>
>>> get_class_that_defined_method(A.test)
<class '__main__.A'>
>>> get_class_that_defined_method(B.test)
<class '__main__.A'>
>>> get_class_that_defined_method(C.test)
<class '__main__.A'>
>>> get_class_that_defined_method(D.test)
<class '__main__.D'>
>>> get_class_that_defined_method(E().test)
<class '__main__.D'>
>>> get_class_that_defined_method(E.test)
<class '__main__.D'>
>>> E().test()
1
Alex solution returns the same results. As long as Alex approach can be used, I would use it instead of this one.
Python 3
Solved it in a very simple way:
str(bar.foo_method).split(" ", 3)[-2]
This gives
'FooClass.foo_method'
Split on the dot to get the class and the function name separately
I found __qualname__ is useful in Python3.
I test it like that:
class Cls(object):
def func(self):
print('1')
c = Cls()
print(c.func.__qualname__)
# output is: 'Cls.func'
def single_func():
print(2)
print(single_func.__module__)
# output: '__main__'
print(single_func.__qualname__)
# output: 'single_func'
After my test, I found another answer here.
I started doing something somewhat similar, basically the idea was checking whenever a method in a base class had been implemented or not in a sub class. Turned out the way I originally did it I could not detect when an intermediate class was actually implementing the method.
My workaround for it was quite simple actually; setting a method attribute and testing its presence later. Here's an simplification of the whole thing:
class A():
def method(self):
pass
method._orig = None # This attribute will be gone once the method is implemented
def run_method(self, *args, **kwargs):
if hasattr(self.method, '_orig'):
raise Exception('method not implemented')
self.method(*args, **kwargs)
class B(A):
pass
class C(B):
def method(self):
pass
class D(C):
pass
B().run_method() # ==> Raises Exception: method not implemented
C().run_method() # OK
D().run_method() # OK
UPDATE: Actually call method() from run_method() (isn't that the spirit?) and have it pass all arguments unmodified to the method.
P.S.: This answer does not directly answer the question. IMHO there are two reasons one would want to know which class defined a method; first is to point fingers at a class in debug code (such as in exception handling), and the second is to determine if the method has been re-implemented (where method is a stub meant to be implemented by the programmer). This answer solves that second case in a different way.
if you get this error:
'function' object has no attribute 'im_class'
try this:
import inspect
def get_class_that_defined_method(meth):
class_func_defided = meth.__globals__[meth.__qualname__.split('.')[0]]
#full_func_name = "%s.%s.%s"%(class_func_defided.__module__,class_func_defided.__name__,meth.__name__)
if inspect.isfunction(class_func_defided):
print("%s is not part of a class."%meth.__name__)
return None
return class_func_defided
sample test:
class ExampleClass:
#staticmethod
def ex_static_method():
print("hello from static method")
def ex_instance_method(self):
print("hello from instance method")
def ex_funct(self):
print("hello from simple function")
if __name__ == "__main__":
static_method_class = get_class_that_defined_method(ExampleClass.ex_static_method)
static_method_class.ex_static_method()
instance_method_class = get_class_that_defined_method(ExampleClass.ex_instance_method)
instance_method_class().ex_instance_method()
function_class = get_class_that_defined_method(ex_funct)

How to inherit from class to modify one of their methods in Python?

I have this Python code:
class Parent(object):
def __init__(self):
self.value = 5
def get_value(self):
return self.value
Now I must modify the get_value method, and I did this:
class Child(Parent):
def get_value(self):
return self.value + 1
As expected, I get this result:
>>> p = Parent()
>>> p.get_value()
5
>>> c = Child()
>>> c.get_value()
6
But I need to get this result:
>>> p = Parent()
>>> p.get_value()
6
In other words, I need to modify the get_value method of Parent class without touching the source code. I've been programming such a long time only in Odoo framework (made with Python 2.7) that I've forgotten things like this, may be this question is duplicated, but I still haven't found a solution.
Can anyone help me, please?
Perhaps this is what you're looking for:
class MyClass:
def MyFunc(self):
return 3
def newFunc(self):
return 4
# set the function equal to the new function
MyClass.MyFunc = newFunc
b = MyClass()
# normally would print 3, but prints 4 due to newFunc(self)
print(b.MyFunc())
I'm not really sure why you would want to do this though. If someone else works on a part of your code and needs to access MyClass.MyFunc() without noticing you've changed it's behavior, it will give them unexpected results.
It may be better to write a child class that does what you want it to do instead.

how to get the class name of a statics method belongs to it [duplicate]

How can I get the class that defined a method in Python?
I'd want the following example to print "__main__.FooClass":
class FooClass:
def foo_method(self):
print "foo"
class BarClass(FooClass):
pass
bar = BarClass()
print get_class_that_defined_method(bar.foo_method)
import inspect
def get_class_that_defined_method(meth):
for cls in inspect.getmro(meth.im_class):
if meth.__name__ in cls.__dict__:
return cls
return None
I don't know why no one has ever brought this up or why the top answer has 50 upvotes when it is slow as hell, but you can also do the following:
def get_class_that_defined_method(meth):
return meth.im_class.__name__
For python 3 I believe this changed and you'll need to look into .__qualname__.
In Python 3, if you need the actual class object you can do:
import sys
f = Foo.my_function
vars(sys.modules[f.__module__])[f.__qualname__.split('.')[0]] # Gets Foo object
If the function could belong to a nested class you would need to iterate as follows:
f = Foo.Bar.my_function
vals = vars(sys.modules[f.__module__])
for attr in f.__qualname__.split('.')[:-1]:
vals = vals[attr]
# vals is now the class Foo.Bar
Thanks Sr2222 for pointing out I was missing the point...
Here's the corrected approach which is just like Alex's but does not require to import anything. I don't think it's an improvement though, unless there's a huge hierarchy of inherited classes as this approach stops as soon as the defining class is found, instead of returning the whole inheritance as getmro does. As said, this is a very unlikely scenario.
def get_class_that_defined_method(method):
method_name = method.__name__
if method.__self__:
classes = [method.__self__.__class__]
else:
#unbound method
classes = [method.im_class]
while classes:
c = classes.pop()
if method_name in c.__dict__:
return c
else:
classes = list(c.__bases__) + classes
return None
And the Example:
>>> class A(object):
... def test(self): pass
>>> class B(A): pass
>>> class C(B): pass
>>> class D(A):
... def test(self): print 1
>>> class E(D,C): pass
>>> get_class_that_defined_method(A().test)
<class '__main__.A'>
>>> get_class_that_defined_method(A.test)
<class '__main__.A'>
>>> get_class_that_defined_method(B.test)
<class '__main__.A'>
>>> get_class_that_defined_method(C.test)
<class '__main__.A'>
>>> get_class_that_defined_method(D.test)
<class '__main__.D'>
>>> get_class_that_defined_method(E().test)
<class '__main__.D'>
>>> get_class_that_defined_method(E.test)
<class '__main__.D'>
>>> E().test()
1
Alex solution returns the same results. As long as Alex approach can be used, I would use it instead of this one.
Python 3
Solved it in a very simple way:
str(bar.foo_method).split(" ", 3)[-2]
This gives
'FooClass.foo_method'
Split on the dot to get the class and the function name separately
I found __qualname__ is useful in Python3.
I test it like that:
class Cls(object):
def func(self):
print('1')
c = Cls()
print(c.func.__qualname__)
# output is: 'Cls.func'
def single_func():
print(2)
print(single_func.__module__)
# output: '__main__'
print(single_func.__qualname__)
# output: 'single_func'
After my test, I found another answer here.
I started doing something somewhat similar, basically the idea was checking whenever a method in a base class had been implemented or not in a sub class. Turned out the way I originally did it I could not detect when an intermediate class was actually implementing the method.
My workaround for it was quite simple actually; setting a method attribute and testing its presence later. Here's an simplification of the whole thing:
class A():
def method(self):
pass
method._orig = None # This attribute will be gone once the method is implemented
def run_method(self, *args, **kwargs):
if hasattr(self.method, '_orig'):
raise Exception('method not implemented')
self.method(*args, **kwargs)
class B(A):
pass
class C(B):
def method(self):
pass
class D(C):
pass
B().run_method() # ==> Raises Exception: method not implemented
C().run_method() # OK
D().run_method() # OK
UPDATE: Actually call method() from run_method() (isn't that the spirit?) and have it pass all arguments unmodified to the method.
P.S.: This answer does not directly answer the question. IMHO there are two reasons one would want to know which class defined a method; first is to point fingers at a class in debug code (such as in exception handling), and the second is to determine if the method has been re-implemented (where method is a stub meant to be implemented by the programmer). This answer solves that second case in a different way.
if you get this error:
'function' object has no attribute 'im_class'
try this:
import inspect
def get_class_that_defined_method(meth):
class_func_defided = meth.__globals__[meth.__qualname__.split('.')[0]]
#full_func_name = "%s.%s.%s"%(class_func_defided.__module__,class_func_defided.__name__,meth.__name__)
if inspect.isfunction(class_func_defided):
print("%s is not part of a class."%meth.__name__)
return None
return class_func_defided
sample test:
class ExampleClass:
#staticmethod
def ex_static_method():
print("hello from static method")
def ex_instance_method(self):
print("hello from instance method")
def ex_funct(self):
print("hello from simple function")
if __name__ == "__main__":
static_method_class = get_class_that_defined_method(ExampleClass.ex_static_method)
static_method_class.ex_static_method()
instance_method_class = get_class_that_defined_method(ExampleClass.ex_instance_method)
instance_method_class().ex_instance_method()
function_class = get_class_that_defined_method(ex_funct)

How do you clone a class in Python?

I have a class A and i want a class B with exactly the same capabilities.
I cannot or do not want to inherit from B, such as doing class B(A):pass
Still i want B to be identical to A, yet have a different i: id(A) != id(B)
Watch out, i am not talking about instances but classes to be cloned.
I'm pretty sure whatever you are trying to do can be solved in a better way, but here is something that gives you a clone of the class with a new id:
def c():
class Clone(object):
pass
return Clone
c1 = c()
c2 = c()
print id(c1)
print id(c2)
gives:
4303713312
4303831072
I guess this is not what you wanted but its what the question seems to be asking for...
class Foo(object):
def bar(self):
return "BAR!"
cls = type("Bar", (object,), dict(Foo.__dict__))
print cls
x = cls()
print x.bar()
maybe i misunderstood you question but what about wrapping A in B?
class A:
def foo(self):
print "A.foo"
class B:
def __init__(self):
self._i = A()
def __getattr__(self, n):
return getattr(self._i, n)
You can clone the class via inheritance. Otherwise you are just passing around a reference to the class itself (rather than a reference to an instance of the class). Why would you want to duplicate the class anyway? It's obvious why you would want to create multiple instances of the class, but I can't fathom why you would want a duplicate class. Also, you could simply copy and paste with a new class name...

Get class that defined method

How can I get the class that defined a method in Python?
I'd want the following example to print "__main__.FooClass":
class FooClass:
def foo_method(self):
print "foo"
class BarClass(FooClass):
pass
bar = BarClass()
print get_class_that_defined_method(bar.foo_method)
import inspect
def get_class_that_defined_method(meth):
for cls in inspect.getmro(meth.im_class):
if meth.__name__ in cls.__dict__:
return cls
return None
I don't know why no one has ever brought this up or why the top answer has 50 upvotes when it is slow as hell, but you can also do the following:
def get_class_that_defined_method(meth):
return meth.im_class.__name__
For python 3 I believe this changed and you'll need to look into .__qualname__.
In Python 3, if you need the actual class object you can do:
import sys
f = Foo.my_function
vars(sys.modules[f.__module__])[f.__qualname__.split('.')[0]] # Gets Foo object
If the function could belong to a nested class you would need to iterate as follows:
f = Foo.Bar.my_function
vals = vars(sys.modules[f.__module__])
for attr in f.__qualname__.split('.')[:-1]:
vals = vals[attr]
# vals is now the class Foo.Bar
Thanks Sr2222 for pointing out I was missing the point...
Here's the corrected approach which is just like Alex's but does not require to import anything. I don't think it's an improvement though, unless there's a huge hierarchy of inherited classes as this approach stops as soon as the defining class is found, instead of returning the whole inheritance as getmro does. As said, this is a very unlikely scenario.
def get_class_that_defined_method(method):
method_name = method.__name__
if method.__self__:
classes = [method.__self__.__class__]
else:
#unbound method
classes = [method.im_class]
while classes:
c = classes.pop()
if method_name in c.__dict__:
return c
else:
classes = list(c.__bases__) + classes
return None
And the Example:
>>> class A(object):
... def test(self): pass
>>> class B(A): pass
>>> class C(B): pass
>>> class D(A):
... def test(self): print 1
>>> class E(D,C): pass
>>> get_class_that_defined_method(A().test)
<class '__main__.A'>
>>> get_class_that_defined_method(A.test)
<class '__main__.A'>
>>> get_class_that_defined_method(B.test)
<class '__main__.A'>
>>> get_class_that_defined_method(C.test)
<class '__main__.A'>
>>> get_class_that_defined_method(D.test)
<class '__main__.D'>
>>> get_class_that_defined_method(E().test)
<class '__main__.D'>
>>> get_class_that_defined_method(E.test)
<class '__main__.D'>
>>> E().test()
1
Alex solution returns the same results. As long as Alex approach can be used, I would use it instead of this one.
Python 3
Solved it in a very simple way:
str(bar.foo_method).split(" ", 3)[-2]
This gives
'FooClass.foo_method'
Split on the dot to get the class and the function name separately
I found __qualname__ is useful in Python3.
I test it like that:
class Cls(object):
def func(self):
print('1')
c = Cls()
print(c.func.__qualname__)
# output is: 'Cls.func'
def single_func():
print(2)
print(single_func.__module__)
# output: '__main__'
print(single_func.__qualname__)
# output: 'single_func'
After my test, I found another answer here.
I started doing something somewhat similar, basically the idea was checking whenever a method in a base class had been implemented or not in a sub class. Turned out the way I originally did it I could not detect when an intermediate class was actually implementing the method.
My workaround for it was quite simple actually; setting a method attribute and testing its presence later. Here's an simplification of the whole thing:
class A():
def method(self):
pass
method._orig = None # This attribute will be gone once the method is implemented
def run_method(self, *args, **kwargs):
if hasattr(self.method, '_orig'):
raise Exception('method not implemented')
self.method(*args, **kwargs)
class B(A):
pass
class C(B):
def method(self):
pass
class D(C):
pass
B().run_method() # ==> Raises Exception: method not implemented
C().run_method() # OK
D().run_method() # OK
UPDATE: Actually call method() from run_method() (isn't that the spirit?) and have it pass all arguments unmodified to the method.
P.S.: This answer does not directly answer the question. IMHO there are two reasons one would want to know which class defined a method; first is to point fingers at a class in debug code (such as in exception handling), and the second is to determine if the method has been re-implemented (where method is a stub meant to be implemented by the programmer). This answer solves that second case in a different way.
if you get this error:
'function' object has no attribute 'im_class'
try this:
import inspect
def get_class_that_defined_method(meth):
class_func_defided = meth.__globals__[meth.__qualname__.split('.')[0]]
#full_func_name = "%s.%s.%s"%(class_func_defided.__module__,class_func_defided.__name__,meth.__name__)
if inspect.isfunction(class_func_defided):
print("%s is not part of a class."%meth.__name__)
return None
return class_func_defided
sample test:
class ExampleClass:
#staticmethod
def ex_static_method():
print("hello from static method")
def ex_instance_method(self):
print("hello from instance method")
def ex_funct(self):
print("hello from simple function")
if __name__ == "__main__":
static_method_class = get_class_that_defined_method(ExampleClass.ex_static_method)
static_method_class.ex_static_method()
instance_method_class = get_class_that_defined_method(ExampleClass.ex_instance_method)
instance_method_class().ex_instance_method()
function_class = get_class_that_defined_method(ex_funct)

Categories

Resources