Реализация интерполяции строк 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 модуль, который я придумал, потому что он меньше печатает, чем любой из них в долгосрочной перспективе. ЛОЛ!

выполнить код здесь:

http://labs.codecademy.com/BE3n/3#:workspace