Где пример метода декоратора?
В моем коде у меня есть метод, который возвращает экземпляр класса, например:
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
Чтобы держать вещи организованными, я собираюсь разместить Реквизит в MyClass. Затем я бы хотел обойти забаву и напрямую сделать класс методом экземпляра MyClass, например так:
class MyClass:
@instancemethod # does not exist!
class fun:
def __init__( self, parent, *args ):
self.parent = parent
self.args = args
Обратите внимание на комментарий - экземпляр метода декоратора не существует.
Есть ли способ сделать это, то есть превратить вызываемый объект в метод экземпляра? Если я изменю @instancemethod на @classmethod, конструкция сработает, за исключением того, что, конечно, parent - это класс, а не экземпляр. Я удивлен, что не могу найти ничего о том, что кажется противоположной операцией.
Любопытно, чтобы это прояснилось!
Редактировать:
Похоже, мой вопрос был неясен. У меня есть функция-член, забавная, которая возвращает не одно значение или кортеж, а объект, полный данных. Эти данные генерируются на основе содержимого объекта MyClass и аргументов функции. Мой исходный код делает именно то, что я хочу. Второй код - это то, как я предпочел бы написать это.
Более того, я заметил, что декоратор, который я ищу, это просто следующее:
def instancemethod( cls ):
def f( *args ):
return cls( *args )
return f
Это, конечно, идентично "веселому" методу, который я стремился обойти. Также обратите внимание, что тривиальные return cls не идентичны, хотя на первый взгляд может показаться, что это так.
С этим декоратором мое определение второго класса является допустимым и дает желаемый результат, а именно, a.fun() возвращает объект, который (потенциально) инициализируется на основе данных в:
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)
Это все еще оставляет меня с вопросом, если метод instance, определенный здесь, не доступен как встроенный в python, потому что он кажется упущением рядом с classmethod и staticmethod. Но, если нет, я полагаю, я могу жить с этой конструкцией.
3 ответа
Я думаю, что вы слишком усложняете вещи без причины; возможно, вы привыкли к другим языкам и хотите перенести свои привычки оттуда.
IIUC, вы намерены сделать что-то вроде:
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)
Я не совсем уверен, что вы пытаетесь сделать, но я подозреваю, что вы хотите прочитать дескрипторы.
По сути, дескриптор является атрибутом класса, который сам по себе является классом, который определяет __get__
а также __set__
методы. В вашем случае вы можете переместить код из Props.__init__
в Props.__set__
, задавать Props
как fun
атрибут класса, и все должно работать так, как вы хотите.
Вы не нуждаетесь в декораторе метода экземпляра, это может работать:
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
Вы также можете изменить свой первый пример на
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