Как использовать setattr для создания связанных методов? - PullRequest
0 голосов
/ 28 февраля 2019

Итак, у меня есть класс с методом, который принимает строку.Примерно так:

class A():

    def func(self, name):
        # do some stuff with it

У меня есть конечное число возможных значений, [val1, val2, val2], например, Все строки.Я хочу использовать их так:

a = A()
a.val1() # actually a.func(val1)

Я пытался объединить декораторы и setattr:

class A():

    def func(self, val):
        # do some stuff with it

    def register(self, val):
        def wrapper(self):
            self.func(val)

        setattr(self, val, wrapper)

Так что я могу перебирать все возможные значения во время выполнения:

a = A()
for val in vals:
    a.register(val)

И это имеет нулевой эффект.Обычно setattr добавляет новый атрибут со значением None, но в этом случае ничего не происходит.Может кто-нибудь объяснить, почему это так и что я могу сделать?

1 Ответ

0 голосов
/ 28 февраля 2019

register() не декоратор, это в основном просто «фабрика функций» с побочными эффектами.Также, как я сказал в комментарии, setattr() необходимо знать, какое имя присвоено значению.

Вот способ заставить ваш код работать:

class A():

    def func(self, val):
        # do some stuff with it
        print('func({}) called'.format(val))

    def register(self, val, name):
        def wrapper():
            self.func(val)
        wrapper.__name__ = name
        setattr(self, name, wrapper)

vals = 10, 20, 30
a = A()

for i, val in enumerate(vals, 1):
    a.register(val, 'val'+str(i))  # Creates name argument.

a.val1()  # -> func(10) called
a.val2()  # -> func(20) called
...