[EDIT 00]: Я редактировал несколько раз сообщение и теперь даже название, пожалуйста, прочитайте ниже.Реализация интерполяции строк Python
Я только что узнал о методе строки формата, и его использование со словарями, как те, предоставляемые vars()
, locals()
и globals()
, например:
name = 'Ismael'
print 'My name is {name}.'.format(**vars())
Но я хочу сделать:
name = 'Ismael'
print 'My name is {name}.' # Similar to ruby
Так что я пришел с этим:
def mprint(string='', dictionary=globals()):
print string.format(**dictionary)
Вы можете взаимодействовать с кодом здесь: http://labs.codecademy.com/BA0B/3#:workspace
Наконец, то, что я хотел бы сделать это, чтобы иметь функцию в другом файле с именем my_print.py
, так что я мог бы сделать:
from my_print import mprint
name= 'Ismael'
mprint('Hello! My name is {name}.')
Но, как прямо сейчас, проблема с областями, как я могу получить пространство имен основного модуля в качестве словаря из импортированной функции mprint. (не от my_print.py
)
Надеюсь, я сделал себе uderstood, если нет, попробуйте импортировать функцию из другого модуля. (трассировка находится в ссылке)
Он обращается к globals()
dict от my_print.py
, но, конечно, имя переменной не определено в этой области, любые идеи о том, как это сделать?
Функция работает, если она определена в том же модуле, но обратите внимание, как я должен использовать globals()
, потому что, если нет, я бы получил только словарь со значениями в пределах mprint()
scope.
Я попытался использовать нелокальную и точечную нотацию для доступа к основным переменным модуля, но я все еще не могу понять это.
[EDIT 01]: Я думаю, что я понял, решение:
В my_print.py:
def mprint(string='',dictionary=None):
if dictionary is None:
import sys
caller = sys._getframe(1)
dictionary = caller.f_locals
print string.format(**dictionary)
В test.py:
from my_print import mprint
name = 'Ismael'
country = 'Mexico'
languages = ['English', 'Spanish']
mprint("Hello! My name is {name}, I'm from {country}\n"
"and I can speak {languages[1]} and {languages[0]}.")
Он печатает:
Hello! My name is Ismael, I'm from Mexico
and I can speak Spanish and English.
Как вы думаете, ребята? Это было сложно для меня!
Мне это нравится, гораздо более удобочитаемо для меня.
[EDIT 02]: Я сделал модуль с interpolate
функции, в Interpolate
классе и попыткой для метода interpolate
класса, аналогичной функции.
У этого есть небольшой набор тестов и документированный!
Я застрял в реализации метода, я не понимаю.
Вот код: http://pastebin.com/N2WubRSB
Как вы думаете, ребята?
[EDIT 03]: Хорошо, я осел только с функцией interpolate()
сейчас.
В string_interpolation.py
:
import sys
def get_scope(scope):
scope = scope.lower()
caller = sys._getframe(2)
options = ['l', 'local', 'g', 'global']
if scope not in options[:2]:
if scope in options[2:]:
return caller.f_globals
else:
raise ValueError('invalid mode: {0}'.format(scope))
return caller.f_locals
def interpolate(format_string=str(),sequence=None,scope='local',returns=False):
if type(sequence) is str:
scope = sequence
sequence = get_scope(scope)
else:
if not sequence:
sequence = get_scope(scope)
format = 'format_string.format(**sequence)'
if returns is False:
print eval(format)
elif returns is True:
return eval(format)
Еще раз спасибо, ребята! Любые мнения?
[EDIT 04]:
Это моя последняя версия, то есть тест, и описывает строки документации некоторые ограничения я нашел: http://pastebin.com/ssqbbs57
Вы можете быстро проверить код здесь : http://labs.codecademy.com/BBMF#:workspace
И клон Grom мерзавец репо здесь: https://github.com/Ismael-VC/python_string_interpolation.git
связанно: [? Является ли строка форматирования, которая тянет переменную из своей вызывающей области видимости плохой практики] (http://stackoverflow.com/questions/13312240/is- a-string-formatter-that-pulls-variables-from-its-call-scope-bad-practice) – jfs
related: [Печать имен и содержимого переменных в качестве инструмента отладки; ищет emacs/Python shortcut] (http://stackoverflow.com/questions/2813227/printing-variable-names-and-contents-as-debugging-tool-looking-for-emacs-python) – jfs
Это интересное упражнение , но я предупреждал бы о таком неявном поведении: Python отговаривает его («Явный лучше, чем неявный» означает здесь, что 'mprint ('...', vars())' лучше, чем 'mprint ('...')' going обратно к вызывающему абоненту и получить его локальные переменные), и я думаю, что он по уважительным причинам (явный код, возможно, легче читать и поддерживать). – EOL