Есть ли способ преобразовать код в строку и наоборот в Python? - PullRequest
3 голосов
/ 28 мая 2010

Оригинальный вопрос был:

Есть ли способ объявить макросы в Python, как они объявлены в C:

#define OBJWITHSIZE(_x) (sizeof _x)/(sizeof _x[0])

Вот что я пытаюсь выяснить:

Есть ли способ избежать дублирования кода в Python? В одной части программы, которую я пишу, у меня есть функция:

def replaceProgramFilesPath(filenameBr):
  def getProgramFilesPath():
    import os
    return os.environ.get("PROGRAMFILES") + chr(92)
  return filenameBr.replace("<ProgramFilesPath>",getProgramFilesPath() )

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

"""
def replaceProgramFilesPath(filenameBr):
  def getProgramFilesPath():
    import os
    return os.environ.get("PROGRAMFILES") + chr(92)
  return filenameBr.replace("<ProgramFilesPath>",getProgramFilesPath() )
"""

Как мне создать "макрос", который позволит избежать этого дублирования?

Ответы [ 7 ]

3 голосов
/ 28 мая 2010

Нет, Python не поддерживает макросы препроцессора, такие как C. Однако, ваш пример не тот, который вам нужно делать в Python; Вы могли бы рассмотреть возможность привести соответствующий пример, чтобы люди могли предложить Pythonic способ выразить то, что вам нужно.

2 голосов
/ 28 мая 2010

Вообще говоря, если вы хотите преобразовать строку в код Python, используйте eval. Вам редко нужно eval в Python. Где-то в стандартной библиотеке есть модуль, который может немного рассказать вам об объектном коде (не работает в интерфейсе), я никогда не использовал его напрямую. Вы можете найти материал на comp.lang.python, который это объясняет.

Что касается макросов 'C', которые, кажется, являются реальным центром вашего вопроса.

прочищает горло НЕ ИСПОЛЬЗУЙТЕ C MACROS В КОДЕ ПИТОНА.

  1. Если все, что вам нужно, это макрос C, используйте процессор предварительной обработки C для предварительной обработки ваших сценариев. Duh.

  2. Если вы хотите #include, это называется импорт.

  3. Если вы хотите #define, используйте неизменный объект. Подумайте, const int foo = 1; вместо #define foo 1. Некоторые объекты являются неизменяемыми, например, кортежи. Вы можете написать функцию, которая делает переменную достаточно неизменной. Поищите в сети пример. В некоторых случаях мне нравятся статические классы.

  4. Если вы хотите FOO (x, y) ... код ...; научитесь использовать функции и классы.

Большинство применений макроса 'CPP' в Python может быть достигнуто написанием функции. Вы можете получить книгу по функциям высшего порядка , чтобы справиться с более сложными случаями. Лично мне нравится книга под названием Perl высшего порядка (HOP), и, хотя она не основана на Python, большая часть книги посвящена независимым от языка идеям - и эти идеи должны быть изучены для каждого программиста.

Для всех намерений и целей единственное использование процессора Pre Pre, которое вам нужно в Python, которое не совсем предусмотрено из коробки, - это возможность # определять константы, что часто неправильно, даже если в C и C ++.

Теперь разумно реализуем макросы lisp в python и действительно нуждаются в них ... прочищает горло и подметает под ковром .

2 голосов
/ 28 мая 2010

Отвечая на новый вопрос.

В вашем первом файле Python (например, называется first.py):

import os

def replaceProgramFilesPath(filenameBr):
  new_path = os.environ.get("PROGRAMFILES") + chr(92)
  return filenameBr.replace("<ProgramFilesPath>", new_path)

Во втором файле Python (называемом, например, second.py):

from first import replaceProgramFilesPath
# now replaceProgramFilesPath can be used in this script.

Обратите внимание, что first.py должен находиться в пути поиска модулей Python или в том же каталоге, что и second.py, чтобы вы могли выполнять импорт в second.py.

2 голосов
/ 28 мая 2010

Это не поддерживается на уровне языка. В Python вы обычно используете обычную функцию или обычную переменную, где вы можете использовать #define в C.

2 голосов
/ 28 мая 2010

Несмотря на то, что, похоже, есть библиотека для предварительной обработки python, называемая pypp , я не совсем знаком с ней. Там действительно нет возможности предварительной обработки для встроенного Python. Код Python переводится в байт-код, промежуточных шагов нет. Если вы новичок в python, я бы рекомендовал полностью избегать pypp.

Ближайшим эквивалентом макросов может быть определение глобальной функции. Эквивалент Python для вашего макроса в стиле C может быть:

import sys
OBJWITHSIZE = lambda x: sys.getsizeof(x) / sys.getsizeof(x[0])
aList = [1, 2, 4, 5]
size = OBJWITHSIZE(aList)
print str(size)

Обратите внимание, что вам редко понадобится получить размер объекта Python, поскольку все операции выделения и удаления обрабатываются для вас в Python, если вы не делаете что-то довольно странное.

Вместо использования лямбда-функции вы также можете сделать это:

import sys
def getSize(x):
   return sys.getsizeof(x) / sys.getsizeof(x[0])

OBJWITHSIZE = getSize
aList = [1, 2, 4, 5]
size = OBJWITHSIZE(aList)
print str(size)

Что по сути то же самое.

Как уже упоминалось ранее, ваш пример макроса избыточен в python, потому что вы можете просто написать:

aList = [1, 2, 4, 5]
size = len(aList)
print str(size)
0 голосов
/ 28 мая 2010

Вы можете записать это во второй файл вместо репликации строки кода

"""
from firstFile import replaceProgramFilesPath
"""
0 голосов
/ 28 мая 2010

Ну, для смелых, есть Метафайт:

http://code.google.com/p/metapython/wiki/Tutorial

For instance, the following MetaPython code:

$for i in range(3):
    print $i

will expand to the following Python code:

print 0
print 1
print 2

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...