Ну, код говорит больше (я жестко закодированы некоторые вещи, чтобы изолировать проблему и сделать вопрос короче):параметр самостоятельно и метапрограммированием
class wrapper:
def __init__(self, func):
self.func = func
def __call__(self, *args):
print("okay, arg = ", args[0])
self.func(self, args)
class M(type):
def __new__(klass, name, bases, _dict):
_dict[ "f" ] = wrapper(_dict[ "f" ])
return type.__new__(klass, name, bases, _dict)
class AM(metaclass = M):
def __init__(self):
self.a = 0
def f(self, a):
self.a = a
am = AM()
print(am.a) # prints 0, expected
am.f(1) # prints: "okay, arg = 1"
print(am.a) # prints 0 again, also expected
Я хочу вторую печать, чтобы показать 1
, вместо 0
. Другими словами, возможно ли, и если да - как, передать «реальное я» в мою обертку?
Примечание: Я знаю почему это печатает 0
и я знаю , что проблема здесь (wrapper
«s само проходит, а объект, который вызывает f
), но я не знаю, как реши это.
Любые идеи?
EDIT - спасибо всем за ответы, +1 от меня. Но я думаю, что мне нужно сделать это с помощью класса, поскольку мне нужно сохранить дополнительную информацию (например, метаданные) (это упрощенная версия моей реальной проблемы). Возможно ли и как, если так? Извините за то, что вы не указали это в самом начале.
Не могли бы вы привести несколько примеров? Я не получил этого, я что-то упустил. (В C++ нет ничего подобного) –
Дескриптор - это просто класс, который Python передает дополнительную информацию об этом классе и экземпляре, к которому он привязан при вызове дескриптора ' __get __() 'или' __set __() '. –
Хм, я вижу. Я думаю, что это сработает для меня. Но тогда, как вызвать функцию с аргументами. '__get__' принимает 3 аргумента -' self, obj, objtype'. В '__init__' я могу сохранить функцию как член, но как насчет аргументов? Кроме того, в '__get__' я не могу вернуть' self.func (obj) '? ('self.func' - это сохраненная cunstion, а obj - вызывающий объект, когда я возвращаю' self.func', это действительно возвращает функцию, но если return 'self.func (obj)' 'None':? I нужно, по-видимому, что первый параметр (self) должен быть явно передан? В противном случае я получаю ошибку за меньшие параметры) Большое спасибо! –