where is the instancemethod decorator?
In my code I have a method that returns an instance of a class, like this:
class MyClass:
def fun( self, *args ): # the method
return Props( self, *args )
class Props: # the returned object
def __init__( self, parent, *args ):
self.parent = parent
self.args = args
To keep things organized I am considering to place Props inside MyClass. I would then like to bypass fun and directly make the class an instance method of MyClass, like this:
class MyClass:
@instancemethod # does not exist!
class fun:
def __init__( self, parent, *args ):
self.parent = parent
self.args = args
Note the comment - the instancemethod decorator does not exist.
Is there a way to do this, i.e. to turn a callable object into an instance method? If I change @instancemethod to @classmethod the construction works, except then of course parent is the class, not the instance. I am surprised that I cannot find anything about what seems to be the opposite operation.
Curious to have this cleared up!
Edit:
It seems that my quest开发者_运维技巧ion was not clear. What I have is a member function, fun, that returns not a single value or tuple but an object full of data. This data is generated based on the contents of the MyClass object and function arguments. My initial code does exactly what I want. The second code is how I would prefer to write it.
Moreover I noticed that the decorator I am looking for is simply the following:
def instancemethod( cls ):
def f( *args ):
return cls( *args )
return f
It is, of course, identical to the 'fun' method that I aimed to bypass. Note also that the trivial 'return cls' is not identical, even though it might seem like that at first sight.
With this decorator, my second class definition is valid and produces the desired result, namely, a.fun() returns an object that is (potentially) initialized based on the data in a:
a = MyClass()
p = a.fun(1,2,3)
print a # <__main__.MyClass instance at 0xb775b84c>
print p.parent # <__main__.MyClass instance at 0xb775b84c>
print p.args # (1, 2, 3)
This still leaves me with the question if the instancemethod defined here is not available as a python builtin, because it seems an omission next to classmethod and staticmethod. But, if not, I suppose I can live with this construction.
I'm not sure exactly what you're trying to do, but I suspect you want to read up on descriptors.
Basically, a descriptor is an attribute of a class that is itself a class that defines __get__
and __set__
methods. In your case, you could move the code from Props.__init__
to Props.__set__
, set Props
as the fun
attribute of the class, and all should work as you want.
I think you're overcomplicating things for no reason; perhaps you're accustomed to other languages and want to bring over your habits from there.
IIUC, you intend to do something like:
class SomeClass:
# typical stuff
def __init__(self, other, arg1, arg2, arg3, arg4):
self.parent= other
# blah blah
class SomeOtherClass:
# initialize in __init__, setup stuff
def __init__(self, initarg1, initarg2):
self.initarg1= initarg1
self.initarg2= initarg2
def fun(self, arg3, arg4):
# return an instance of SomeClass based on
# initargs and arguments
return SomeClass(self, self.initarg1, self.initarg2, arg3, arg4)
You don't need an instancemethod decorator, this could should work:
class MyClass:
class fun:
def __init__( self, parent, *args ):
self.parent = parent
self.args = args
m = MyClass()
f = m.fun(None, 1, 2, 3)
print f.args
You could also change your first example to
class Props:
def __init__( self, parent, *args ):
self.parent = parent
self.args = args
class MyClass:
fun = Props
m = MyClass()
f = m.fun(None, 1, 2, 3)
print f.args
精彩评论