Python как строку преобразовать в функцию

от admin

Как использовать строки для вызова функций/методов?

Лучше всего использовать словарь,который сопоставляет строки с функциями.Основное преимущество этой техники заключается в том,что строки не обязательно должны совпадать с именами функций.Это также основная техника,используемая для эмуляции конструкции case:

Используйте встроенную функцию getattr() :

Обратите внимание, что getattr() работает с любым объектом, включая классы, экземпляры классов, модули и так далее.

Это используется в нескольких местах стандартной библиотеки,например,так:

Используйте locals() для разрешения имени функции:

Существует ли аналог Perl’овской chomp()для удаления новых строк из строк?

Вы можете использовать S.rstrip(«\r\n») для удаления всех вхождений любого терминатора строки из конца строки S без удаления других конечных пробелов. Если строка S представляет более одной строки с несколькими пустыми строками в конце, терминаторы строк для всех пустых строк будут удалены:

Поскольку это обычно требуется только при чтении текста по одной строке за раз, использование S.rstrip() таким образом работает хорошо.

Существует ли эквивалент scanf()или sscanf()?

Для простого синтаксического анализа ввода самый простой подход обычно состоит в том, чтобы разбить строку на слова, разделенные пробелами, с помощью метода split() строковых объектов, а затем преобразовать десятичные строки в числовые значения с помощью int() или float() . split() поддерживает необязательный параметр «sep», который полезен, если в строке в качестве разделителя используется что-то отличное от пробела.

Для более сложного анализа ввода регулярные выражения более эффективны, чем sscanf() в C, и лучше подходят для этой задачи.

Что означает ошибка ‘UnicodeDecodeError’ или ‘UnicodeEncodeError’?

Performance

Моя программа работает слишком медленно.Как мне ускорить ее?

Это вообще сложный вопрос.Во-первых,вот список вещей,о которых следует помнить,прежде чем погружаться дальше:

  • Характеристики производительности различаются в зависимости от реализации Python. Этот FAQ посвящен CPython .
  • Поведение может отличаться в разных операционных системах,особенно когда речь идет о вводе/выводе или многопоточности.
  • Вы всегда должны находить горячие точки в своей программе, прежде чем пытаться оптимизировать какой-либо код (см. Модуль profile
  • Написание сценариев тестов позволит вам быстро выполнять итерацию при поиске улучшений (см . Модуль timeit ).
  • Настоятельно рекомендуется иметь хорошее покрытие кода (с помощью модульного тестирования или любой другой техники),прежде чем потенциально внедрять регрессии,скрытые в сложных оптимизациях.

Тем не менее,существует множество приемов для ускорения кода на Python.Вот несколько общих принципов,которые помогут достичь приемлемого уровня производительности:

  • Ускорение работы алгоритмов (или переход на более быстрые алгоритмы)может принести гораздо больше пользы,чем попытка рассыпать по всему коду трюки микрооптимизации.
  • Используйте правильные структуры данных. Изучите документацию по встроенным типам и модулю collections
  • Когда стандартная библиотека предоставляет примитив для выполнения чего-либо, он, скорее всего (хотя и не гарантируется), будет быстрее любой альтернативы, которую вы можете придумать. Это вдвойне верно для примитивов, написанных на C, таких как встроенные функции и некоторые типы расширений. Например, обязательно используйте либо встроенный метод list.sort() ,либо связанную с ним функцию sorted(sorted() для выполнения сортировки (и см. Sorting HOW TO для примеров умеренно сложного использования).
  • Абстракции,как правило,создают косвенность и заставляют интерпретатор работать больше.Если уровни непрямолинейности перевешивают количество проделанной полезной работы,ваша программа будет работать медленнее.Вам следует избегать чрезмерной абстракции,особенно в виде крошечных функций или методов (которые также часто вредят читабельности).

Если вы достигли предела того, что может позволить чистый Python, есть инструменты, которые уведут вас еще дальше. Например, Cython может скомпилировать слегка измененную версию кода Python в расширение C и может использоваться на многих различных платформах. Cython может использовать преимущества компиляции (и необязательных аннотаций типов), чтобы сделать ваш код значительно быстрее, чем при интерпретации. Если вы уверены в своих навыках программирования на C, вы также можете самостоятельно написать модуль расширения C.

Каков наиболее эффективный способ конкатенации многих строк вместе?

str и bytes являются неизменяемыми, поэтому объединение множества строк вместе неэффективно, так как каждое объединение создает новый объект. В общем случае общая стоимость выполнения зависит от общей длины строки в квадрате.

Чтобы накопить много объектов str , рекомендуется поместить их в список и вызвать str.join() в конце:

(другая достаточно эффективная идиома — использовать io.StringIO )

Для накопления объектов с большим количеством bytes рекомендуется расширить объект bytearray с помощью конкатенации на месте ( оператор += ):

Sequences (Tuples/Lists)

Как преобразовать кортежи в списки?

Кортеж конструктора типа tuple(seq) преобразует любую последовательность (фактически, любую итерацию) в кортеж с теми же элементами в том же порядке.

Например, tuple([1, 2, 3]) дает (1, 2, 3) а tuple(‘abc’) дает (‘a’, ‘b’, ‘c’) . Если аргумент является кортежем, он не создает копию, а возвращает тот же объект, поэтому можно дешево вызвать tuple() , когда вы не уверены, что объект уже является кортежем.

Список конструкторов типов list(seq) преобразует любую последовательность или итерацию в список с теми же элементами в том же порядке. Например, list((1, 2, 3)) возвращает [1, 2, 3] а list(‘abc’) возвращает [‘a’, ‘b’, ‘c’] . Если аргумент является списком, он создает копию так же, как и seq[:] .

Что такое отрицательный индекс?

Последовательности Python индексируются положительными и отрицательными числами. Для положительных чисел 0 — это первый индекс, 1 — второй индекс и так далее. Для отрицательных индексов -1 — последний индекс, -2 — предпоследний (предпоследний) индекс и так далее. Считайте seq[-n] тем же, что и seq[len(seq)-n] .

Использование отрицательных индексов может быть очень удобным. Например , S[:-1] — это вся строка, за исключением ее последнего символа, который полезен для удаления завершающей новой строки из строки.

Как выполнить итерацию последовательности в обратном порядке?

Используйте встроенную функцию reversed()

Это не тронет вашу исходную последовательность,но создаст новую копию с обратным порядком для итераций.

Как удалить дубликаты из списка?

См.поваренную книгу Python Cookbook,где подробно рассматривается множество способов сделать это:

Если вы не против изменить порядок списка,отсортируйте его,а затем сканируйте с конца списка,удаляя дубликаты по ходу дела:

Если все элементы списка могут использоваться в качестве заданных ключей (т. е. все они хэшируемые ), это часто бывает быстрее .

Это преобразует список в набор,удаляя таким образом дубликаты,а затем снова в список.

Как удалить несколько элементов из списка

Как и в случае удаления дубликатов,явная итерация в обратном направлении с условием удаления является одной из возможностей.Однако проще и быстрее использовать замену срезов с неявной или явной прямой итерацией.Вот три варианта.

Понимание списка может быть самым быстрым.

Как создать массив в Python?

По своей временной сложности списки эквивалентны массивам в C или Pascal;основное отличие заключается в том,что список Python может содержать объекты многих различных типов.

Читать:
Назад как карточка n

Модуль array также предоставляет методы для создания массивов фиксированных типов с компактными представлениями, но они индексируются медленнее, чем списки. Также обратите внимание, что NumPy и другие сторонние пакеты также определяют структуры, подобные массивам, с различными характеристиками.

Чтобы получить связные списки в стиле Lisp,вы можете эмулировать ячейки cons с помощью кортежей:

Если требуется изменчивость, вы можете использовать списки вместо кортежей. Здесь аналог lisp car — lisp_list[0] , а аналог cdr — lisp_list[1] . Делайте это только в том случае, если вы уверены, что вам это действительно нужно, потому что обычно это намного медленнее, чем использование списков Python.

Как создать многомерный список?

Вы,вероятно,пытались создать многомерный массив подобным образом:

При печати все выглядит правильно:

Но когда вы присваиваете значение,оно появляется в нескольких местах:

Причина в том, что репликация списка с * не создает копии, а создает только ссылки на существующие объекты. *3 создает список, содержащий 3 ссылки на один и тот же список длины два. Изменения в одной строке будут отображаться во всех строках, а это почти наверняка не то, что вам нужно.

Предлагаемый подход заключается в том,чтобы сначала создать список нужной длины,а затем заполнить каждый элемент вновь созданным списком:

Это создаст список,содержащий 3 различных списка длины два.Вы также можете использовать понимание списка:

Или вы можете использовать расширение, предоставляющее матричный тип данных; NumPy является наиболее известным.

Python: Convert string into function name; getattr or equal?

I am editing PROSS.py to work with .cif files for protein structures. Inside the existing PROSS.py, there is the following functions (I believe that’s the correct name if it’s not associated with any class?), just existing within the .py file:

I am adding an optons parser for command line arguments, and one of the options is to specify an alternate method to use besides unpack_pdb_line. So the pertinent part of the options parser is:

However, options.unpack_method is a string and I need to use the function with the same name as the string inside options.unpack_method. How do I use getattr etc to convert the string into the actual function name?

5 Answers 5

Usually you just use a dict and store (func_name, function) pairs:

If you want to exploit the dictionaries (&c) that Python’s already keeping on your behalf, I’d suggest:

Как преобразовать строку в имя функции в Python?

Есть ли способ использовать w, чтобы обратиться к функции добавить?

8 ответов

Если вы реализуете приложение, похожее на оболочку, в котором пользователь вводит какую-то команду (например, add ), а приложение отвечает (возвращает сумму), вы можете использовать модуль cmd , который обрабатывает все командные взаимодействия и диспетчеризацию для вас. Вот пример:

Вот пример бегущей сессии:

$ python cmd_tryout.py
введите help для получения списка допустимых команд
(Cmd) помочь добавить
add — добавляет два числа к распечатке суммы
(Cmd) добавить 5 3
8
(Cmd) выйти

В командной строке (Cmd) вы можете ввести команду help , которую вы получаете бесплатно. Другими командами являются add и quit , которые соответствуют функциям do_add() и do_quit() .

Обратите внимание, что команда help отображает строку документации для вашей функции. Строка документа — это строка, следующая сразу за декларацией функции (см., Например, do_add() ).

Модуль cmd не разбивает и не разбирает аргументы, поэтому вам придется делать это самостоятельно. Функция do_add() это иллюстрирует.

Этого примера программы должно быть достаточно, чтобы вы начали. Для получения дополнительной информации перейдите на cmd справочную страницу. Это мелочи, чтобы настроить подсказку и другие аспекты вашей программы.

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

Как преобразовать строку в функцию в python?

есть ли способ использовать w для ссылки на функцию add?

8 ответов

поскольку вы принимаете пользовательский ввод, самый безопасный способ-точно определить, что является допустимым вводом:

если вы хотите оценить строки типа ‘add(3,4)’ , вы могли бы использовать безопасный eval:

eval вообще может быть опасно при применении к пользовательскому вводу. выше безопаснее, так как __builtins__ отключена и locals ограничен dispatcher . Кто-то более умный, чем я, возможно, все еще способен причинить неприятности, но я не могу сказать тебе, как. сделать его.

предупреждение: даже eval(. <'__builtins__':None>, dispatcher) is небезопасных для применения к пользовательскому вводу. Злонамеренный пользователь!—24—>может запускать произвольные функции на вашем компьютере если предоставляется возможность оценить его строку с помощью eval .

один безопасный способ-сопоставить имена с функциями. Это безопаснее, чем использовать eval .

решение unutbu-это то, что я обычно использую, но для полноты:

Если вы указываете точное имя функции, вы можете использовать eval , хотя это очень обескураживает, потому что люди могут делать злые вещи:

встроенная функция eval будет делать то, что вы хотите. Применяются все обычные предупреждения о выполнении произвольного пользовательского кода.

Если есть конечное число стандартных функций, вы должны избегать eval и вместо этого используйте таблицу поиска (т. е. Dict ). Никогда не доверяйте своим пользователям.

если вы реализуете оболочечное приложение, в котором пользователь вводит некоторую команду (например,добавить), и ответы приложения (вернуть сумму), вы можете использовать cmd модуль, который обрабатывает все командные взаимодействия и диспетчеризацию для вас. Вот пример:

вот пример тренировки:

$ python cmd_tryout.py
введите help для списка допустимых команд
(Cmd)помогите добавить
add-добавляет два числа печать суммы
(Cmd)добавить 5 3
8
(Cmd)quit

в строке (Cmd), вы можете оформить help команда, которую вы получаете бесплатно. Другие команды add и quit , которые соответствуют do_add() и do_quit() функции.

обратите внимание, что команда help отображает docstring для вашей функции. Docstring-это строка сразу следует declararation функции (см. do_add() например).

на cmd модуль не делает никакого разбиения аргументов, разбора, поэтому вы должны сделать это сами. The do_add() функция иллюстрирует это.

этого примера программы должно быть достаточно, чтобы вы начали. Для получения дополнительной информации посмотрите cmd страница справки. Это мелочи, чтобы настроить приглашение и другой аспект вашей программы.

у меня было много ситуаций, когда мне нужно было сравнить строку с int и наоборот в шаблоне Django.

Я создал фильтр, который позволил мне передать имя функции и использование eval() преобразовать его.

Похожие статьи