Нужна ли в Python функция nonlocals() наряду с globals(), locals()?
Иногда удобно использовать функцию globals(). В примере ниже я создаю словарь функций, используя некоторые соглашения, а именно - первый символ имени функции должен совпадать с ключом:
def a_fun(c):
print(c, 'from a_fun')
def b_fun(c):
print(c, 'from b_fun')
def fun():
fun_dict = dict.fromkeys({'a', 'b'})
return {key: globals()[key + '_fun'] for key in fun_dict}
fun()['a'](33), fun()['b'](44)
код прекрасно себе работает и выдает:
33 from a_fun
44 from b_fun
Но вот при описании класса так не получается. Мне удалось только так:
class fabric():
def __a_fun(self, c):
print(c, 'from __a_fun')
def __b_fun(self, c):
print(c, 'from __b_fun')
def fun(self):
# print(locals())
# print(globals())
return {'a': self.__a_fun, 'b': self.__b_fun}
z = fabric()
z.fun()['a'](33)
что дает
33 from __a_fun
Проблема в том, что __a_fun и __b_fun отсутствуюьт в словарях locals() и globals().
Подскажите, можно ли это реализовать по аналогии с первым примером? Идея в том, чтобы не менять код при добавлении очередного варианта обработки данных. Ну если что-то поменялось - я просто добавлю еще одну функцию в файл и не нужно менять в другом месте.
То есть вопрос об автоматическом заполнении словаря с функциями внутри класса.
Ответы (1 шт):
Все названия методов класса можно достать из self.__class__.__dict__ и начинаться они там будут с self.__class__.__name__:
class fabric():
def __a_fun(c):
print(c, 'from __a_fun')
def __b_fun(c):
print(c, 'from __b_fun')
def fun(self):
fun_dict = dict.fromkeys({'a', 'b'})
return {key: self.__class__.__dict__['_' + self.__class__.__name__ + '__' + key + '_fun'] for key in fun_dict}
z = fabric()
z.fun()['a'](33), z.fun()['b'](44)
Вывод:
33 from __a_fun
44 from __b_fun
Вариант, чтобы не прописывать словарь, а всё брать из класса:
def fun(self):
postfix = '_fun'
cut = -len(postfix)
return {k[cut-1:cut]: v for k,v in self.__class__.__dict__.items() if callable(v) and k.endswith(postfix)}