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.
Related
I have a function which returns a class:
def my_function():
# some logic
class AClass:
def __init__(self, argument):
init()
return AClass
And when I call this function, it returns a class, not an object of that class, right?
Value = my_function()
My question is how can I create an object from that class AClass?
Thank you.
my_class = my_function()
my_obj = my_class(arg)
Since the method returns a reference to a type you can simply use whatever constructor that is defined for the class directly on the return value.
Take this class for example:
class A:
def __init_(self, n = 0):
self.__n = n
Lets see what happens when reference the type directly when running the interpreter interactively:
>>> A
<class `__main__.A`>
Now lets return the type in a method:
>>> def f():
>>> return A
>>> f()
<class `__main__.A`>
Since the value of referencing the class directly and when returned from a method is the same, you can use that returned value the same you would normally. Therefore a = A() is the same as a = f()(). Even if the class takes parameter you can still reference it directly: a = f()(n = 10)
I may be trying to do something that is outside of the realm of possibility here, but I figured I would ask first before abandoning hope. So here it goes...
I have 2 classes, A and B. Each class has an arbitrary number of functions. Class B will be instantiated somewhere in Class A and Class A will utilize one of Class B functions via that instantiation. A function in Class B will need to refer to one or more of Class A's functions using it's current instantiation data of Class A.
Class A
#!/usr/bin/python
from classB import classB
class classA(object):
def Apple(self):
print("Inside Apple")
b = classB()
b.Banana()
b.bar()
def foo(self):
print("foo inside apple")
a = classA()
a.Apple()
Class B:
#!/usr/bin/python
import inspect
class classB(object):
def Banana(self):
print("Inside banana")
def bar(self):
print("bar inside banana")
'''
The following lines just show I can get the names of the
calling class and methods.
'''
stack = inspect.stack()
the_class = stack[1][0].f_locals["self"].__class__
the_method = stack[1][0].f_code.co_name
print("Caller Class: {}".format(the_class))
print("Caller Method: {}".format(the_method))
function_name = 'foo'
if hasattr(the_class, function_name):
print("Class {} has method {}".format(the_class,
function_name))
getattr(the_class, function_name)()
I get the following error:
getattr(the_class, function_name)()
TypeError: unbound method foo() must be called with classA instance as first argument (got nothing instead)
Thanks!
As the error suggests, you must build an object of classA (i.e. the_class) before calling getattr on it.
objA = the_class()
But taking a step back, why don't you just pass class A to class B while initializing it?
b = classB(self)
That will allow you to access the exact method of class A that you need.
Else, if method 'foo' in class A is supposed to be a static method, make it so by using #staticmethod decorator.
I have a class and a normal constructor but I wish to preprocess the parameters and postprocess the result so I provide a mandated Factory constructor. Yes, I know that this is an unusual meaning for Factory and I also know that I could use memoization to do my processing but I had problems with extending a memoized class.
I wish to prevent myself from accidentally using the normal constructor and this is one way of doing it.
import inspect
class Foo():
def __init__(self):
actual_class_method = Foo.Factory
# [surely there's a way to do this without introspection?]
allowed_called_from = {name:method for name,method in inspect.getmembers(Foo, inspect.ismethod)}['Factory']
actual_called_from = inspect.currentframe().f_back.f_code # .co_name)
print("actual class method = ",actual_class_method," id = ",id(actual_class_method),",name = ",actual_class_method.__name__)
print("allowed called from = ",allowed_called_from,", id = ",id(allowed_called_from),", name =",allowed_called_from.__name__)
print()
print("actual called from = ",actual_called_from,", id = ",id(actual_called_from),", name =",actual_called_from.co_name)
#classmethod
def Factory(cls):
Foo()
Foo.Factory()
produces output
actual class method = <bound method Foo.Factory of <class '__main__.Foo'>> id = 3071817836 ,name = Factory
allowed called from = <bound method Foo.Factory of <class '__main__.Foo'>> , id = 3072138412 , name = Factory
actual called from = <code object Factory at 0xb7118f70, file "/home/david/Projects/Shapes/rebuild-v0/foo.py", line 15> , id = 3071381360 , name = Factory
Suppose I wished to check that the constructor to Foo() had been called from its Factory. I can find various things about the method whence Foo() was called such as its name and the filename where it was compiled, and this would be sufficient to stop me accidentally calling it directly, but I can't see a way of saying (the method that Foo() was called from) is (the method Factory() in the class Foo). Is there a way of doing this?
Alex Martelli posted an answer.
This might get you what you want:
class Foo:
def __init__(self):
print('Foo.__init__') # might consider throwing an exception
#classmethod
def makeit(cls):
self = cls.__new__(cls)
self.foo = 'foo'
return self
f = Foo() # accidentally create Foo in the usual way
g = Foo.makeit() # use the 'One True Way' of making a Foo
print(g.foo)
print(f.foo)
Output:
Foo.__init__
foo
Traceback (most recent call last):
File "D:\python\soMetaClassWorkAroundInit.py", line 19, in <module>
print(f.foo)
AttributeError: 'Foo' object has no attribute 'foo'
without inspect, you could provide a default argument to your constructor and check that the value passed is the one you're expecting (with default value at 0)
only the factory has a chance to pass the correct initialization value (or someone really wanting to call the constructor, but not by accident)
class Foo():
__MAGIC_INIT = 12345678
def __init__(self,magic=0):
if magic != self.__MAGIC_INIT:
raise Exception("Cannot call constructor, use the factory")
#classmethod
def Factory(cls):
return Foo(magic=Foo.__MAGIC_INIT)
f = Foo.Factory() # works
f = Foo() # exception
another variation would be to toggle a private "locking" boolean. If set to True, crash when entering constructor, else let it do its job, then reset to True.
Of course the factor has access to this boolean, and can set it to False before calling the constructor:
class Foo():
__FORBID_CONSTRUCTION = True
def __init__(self):
if self.__FORBID_CONSTRUCTION:
raise Exception("Cannot call constructor, use the factory")
Foo.__FORBID_CONSTRUCTION = True # reset to True
#classmethod
def Factory(cls):
Foo.__FORBID_CONSTRUCTION = False
return Foo()
f = Foo.Factory()
print("OK")
f = Foo()
not an issue even if multithreaded thanks to python GIL.
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()
I have two methods, one for the individual Instance, and one for every Instance in that class:
class MasterMatches(models.Model):
#classmethod
def update_url_if_any_matches_has_one(cls):
# apply to all instances, call instance method.
def update_url_if_any_matches_has_one(self):
# do something
Should I name these the same? Or, what is a good naming convention here?
The question of using the same names can be clarified by understanding how decorators work.
#dec
def foo(x):
print(x)
translates to
def foo(x):
print(x)
foo = dec(foo)
In your example the decorator syntax can be expanded to
class MasterMatches(models.Model):
def update_url_if_any_matches_has_one(cls):
# apply to all instances, call instance method.
update_url_if_any_matches_has_one = classmethod(update_url_if_any_matches_has_one)
def update_url_if_any_matches_has_one(self):
# do something
The former implementation of update_url_if_any_matches_has_one will be overwritten by the latter.
Usually use self declaration style. #classmethod use only if method not works with class instance fields.
Function decorated as #classmethod takes the first argument is the class type, while normal method takes instance of object.
class A:
#classmethod
def a(cls):
print(cls)
def b(self):
print(self)
a = A()
a.a()
a.b()
# Output:
# <class '__main__.A'>
# <__main__.A object at 0x03FC5DF0>
It can be useful if you have a static class fields. The to access therm you don't need explicitly specify the class name. But you don't get access to instance fields. Example:
class A:
field = 1
#classmethod
def a(cls):
print(cls.field)
def b(self):
self.field = 2
print(self.field, A.field)
a = A()
a.a()
a.b()
# Outputs:
# 1
# 2 1