У меня урок:

class SimpleClass:
    def __init__(self):
        pass

    def init_levels(self):
        levels = get_levels_list()
        for level in levels:
            Transplant(foo, Simplelog, method_name=level)

Transplant - это класс для динамического добавления методов в класс:

class Transplant:
    def __init__(self, method, host, method_name=None):
        self.host = host
        self.method = method
        self.method_name = method_name
        setattr(host, method_name or method.__name__, self)

    def __call__(self, *args, **kwargs):
        nargs = [self.host]
        nargs.extend(args)
        return apply(self.method, nargs, kwargs)

Foo - это функция для «пересадки»:

def foo(self):
    return

Как я могу получить имя вызываемого метода внутри foo?

Например я выполняю:

simpleinst = SimpleClass()
simpleinst.init_levels()

Как я могу изменить свой код для получения имени вызываемого метода в теле определения foo?

0
SkyFox 4 Фев 2013 в 15:04

3 ответа

Лучший ответ

Вы должны будете передать это явно:

class Transplant:
    def __init__(self, method, host, method_name=None):
        self.host = host
        self.method = method
        self.method_name = method_name or method.__name__
        setattr(host, method_name or method.__name__, self)

    def __call__(self, *args, **kwargs):
        nargs = [self.host, self.method_name]
        nargs.extend(args)
        return apply(self.method, nargs, kwargs)

И расширить foo, чтобы принять это в качестве аргумента.

2
Martijn Pieters 4 Фев 2013 в 11:19

Вы можете сделать это с помощью фабрики функций, make_foo:

Ключевым шагом является переопределение атрибута функции func_name:

foo.func_name = name

class SimpleClass:
    def init_levels(self):
        levels = ['foo', 'bar']
        for level in levels:
            # Your original code defined this on `SimpleLog`. Did you mean `SimpleClass`?
            setattr(SimpleClass, level, make_foo(level))

def make_foo(name):
    def foo(self):
        print('{n} has been called'.format(n = foo.func_name))

    foo.func_name = name
    return foo

simpleinst = SimpleClass()
simpleinst.init_levels()
simpleinst.foo()
# foo has been called
simpleinst.bar()
# bar has been called
0
unutbu 4 Фев 2013 в 11:17

Вы смотрели на getattr?

getattr(self, "method")
1
danodonovan 4 Фев 2013 в 11:14