Python 3: строки в переменную с пониманием списка - PullRequest
0 голосов
/ 26 февраля 2020

В Python 2.7 Я имел обыкновение использовать следующий код (я использую пакет emcee ):

def main():
    from emcee import moves
    emcee_moves = ['KDEMove(),0.5', 'DEMove(),0.5']
    mv = [(eval("moves." + _)) for _ in emcee_moves]

if __name__ == '__main__':
    main()

Я использую это, потому что я кормлю «перемещается» через файл входных параметров (это небольшая часть гораздо большего кода), что означает, что они читаются как строки. В Python 3.x теперь выдается:

*** NameError: name 'moves' is not defined

Это, по-видимому, связано с этим исправлением ошибка , как упоминалось в этом старом вопросе: Eval scope в Python 2 против 3 .

Я также читал, что использование eval() обычно не рекомендуется. Мой вопрос заключается в следующем: как мне повторить приведенный выше код, который работал в Python 2,7?


Edit

Это фактический код, который выходит из строя. Она должна быть внутри функции, иначе она не выйдет из строя.

Ответы [ 3 ]

2 голосов
/ 26 февраля 2020

Как сказал Пит, ваш пример работает на python 3.6.8. Однако, другой способ сделать то, что вы хотите:

from emcee import moves
emcee_moves = [('KDEMove', 0.5), ('DEMove', 0.5)]
mv = [(getattr(moves, method)(), val) for method, val in emcee_moves]

getattr, как правило, безопаснее, чем eval.

0 голосов
/ 26 февраля 2020

Хотя I have Python 3.8.0 and the code works as expected - without any errors., как говорится в моем комментарии, все еще возможно сделать это без каких-либо eval().

. Вы хотите динамически получить класс из модуля. Вы можете использовать getattr() для этого.

from emcee import moves
emcee_moves = ['KDEMove', 'DEMove']
mv = [getattr(moves, _)() for _ in emcee_moves]

Вывод:

In [22]: mv = [getattr(moves, _)() for _ in emcee_moves]

In [23]: mv
Out[23]:
[<emcee.moves.kde.KDEMove at 0x7f2bf8b98a90>,
 <emcee.moves.de.DEMove at 0x7f2bf90b08e0>]

Я не совсем уверен, почему эти ,0.5 суффиксы были там (__init__ аргументы, может быть?) , но «суть этого» написана выше.

0 голосов
/ 26 февраля 2020

Вы всегда можете заменить понимание списка обычным l oop. Менее причудливый, но дает ту же функциональность.

...