Реализация интерполяции строки Python
[EDIT 00]: я несколько раз редактировал пост, а теперь даже заголовок, пожалуйста, прочитайте ниже.
Я только что узнал о методе форматной строки и его использовании со словарями, такими как предоставленные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
)
Надеюсь, я понял, если нет, попробуйте импортировать функцию из другого модуля. (обратная связь есть в ссылке)
Это доступ кglobals()
диктовать отmy_print.py
, но, конечно, имя переменной не определено в этой области, есть идеи, как этого добиться?
Функция работает, если она определена в том же модуле, но обратите внимание, как я должен использоватьglobals()
потому что в противном случае я бы только получить словарь со значениями вmprint()
объем.
Я пытался использовать нелокальные и точечные обозначения для доступа к переменным основного модуля, но я до сих пор не могу понять это.
[РЕДАКТИРОВАТЬ 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.
Что вы думаете, ребята? Это было трудно для меня!
Мне это нравится, гораздо более читабельно для меня.
[РЕДАКТИРОВАТЬ 02]: я сделал модуль сinterpolate
функция,Interpolate
класс и попыткаinterpolate
Метод класса, аналогичный функции.
Он имеет небольшой набор тестов и задокументирован!
Я застрял с реализацией метода, я не понимаю.
Вот код:http://pastebin.com/N2WubRSB
Что вы думаете, ребята?
[РЕДАКТИРОВАТЬ 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)
Еще раз спасибо, ребята! Есть мнения?
[РЕДАКТИРОВАТЬ 04]:
Это моя последняя версия, в ней есть тест, строки документации и описаны некоторые ограничения, которые я нашел:http://pastebin.com/ssqbbs57
Вы можете быстро проверить код здесь:http://labs.codecademy.com/BBMF#:workspace
И клон Grom Git репо здесь:https://github.com/Ismael-VC/python_string_interpolation.git