Реализация интерполяции строк Python
[EDIT 00]: я редактировал несколько раз сообщение и теперь даже название, пожалуйста, прочитайте ниже.
я только что узнал о методе format string и его использовании со словарями, такими как те, которые предоставляются 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()
объем.
я попытался использовать нелокальные и точечные обозначения для доступа основные переменные модуля, но я все еще не могу понять это.
[EDIT 01]: думаю, я нашел решение:
In 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)
In 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]: Я сделал модуль с
3 ответов
модули не разделяют пространства имен в python, поэтому globals()
на my_print
всегда будет globals()
of my_print.py файл; i.e место, где функция была фактически определена.
def mprint(string='', dic = None):
dictionary = dic if dic is not None else globals()
print string.format(**dictionary)
вы должны передать globals() текущего модуля явно, чтобы заставить его работать.
Ans не используют изменяемые объекты в качестве значений по умолчанию в функциях python, это может привести к неожиданные результаты. Использовать None
в качестве значения по умолчанию.
A простой пример понимания областей в модулях:
файл : my_print.py
x = 10
def func():
global x
x += 1
print x
файл : main.py
from my_print import *
x = 50
func() #prints 11 because for func() global scope is still
#the global scope of my_print file
print x #prints 50
часть вашей проблемы-ну, причина ее не работает-выделена в этот вопрос.
вы можете иметь вашу работу функции путем проходить внутри globals()
в качестве второго аргумента, mprint('Hello my name is {name}',globals())
.
хотя это может быть удобно в Ruby, я бы рекомендовал вам не писать Ruby в Python, если вы хотите максимально использовать язык.
Языковой Дизайн-Это Не Просто Решение Головоломок:;)
http://www.artima.com/forums/flat.jsp?forum=106&thread=147358
Edit: PEP-0498 решает эту проблему!
The Template
класс string
модуль, также делает то, что мне нужно (но больше похоже на строку format
способ), в итоге она также имеет удобочитаемость я ищу, это также рекомендуется эксплицитности, это в стандарте Библиотека и она также могут быть легко настроены и расширены.
http://docs.python.org/2/library/string.html?highlight=template#string.Template
from string import Template
name = 'Renata'
place = 'hospital'
job = 'Dr.'
how = 'glad'
header = '\nTo Ms. {name}:'
letter = Template("""
Hello Ms. $name.
I'm glad to inform, you've been
accepted in our $place, and $job Red
will ${how}ly recieve you tomorrow morning.
""")
print header.format(**vars())
print letter.substitute(vars())
самое смешное, что теперь я все больше люблю использовать {}
вместо $
и мне все еще нравится string_interpolation
модуль, который я придумал, потому что он меньше печатает, чем любой из них в долгосрочной перспективе. ЛОЛ!
выполнить код здесь: