Python字符串插值实现
[编辑00]:我已经编辑了几次这篇文章,现在连标题都改了,请看下面 我刚刚了解了format string方法,以及它在字典中的使用,比如Python字符串插值实现,python,string-interpolation,Python,String Interpolation,[编辑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(s
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)
您可以在此处与代码交互:
最后,我想做的是在另一个名为my_print.py
的文件中使用该函数,以便执行以下操作:
from my_print import mprint
name= 'Ismael'
mprint('Hello! My name is {name}.')
但就目前而言,作用域存在一个问题,如何从导入的mprint函数中获取作为字典的主模块名称空间。(不是来自my_print.py
的)
我希望我自己做了uderstood,如果没有,请尝试从另一个模块导入该函数。(回溯在链接中)
它正在从my_print.py
访问globals()
dict,但是当然变量名没有在该范围内定义,您知道如何实现吗
如果函数在同一个模块中定义,则该函数可以工作,但请注意我必须如何使用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]:我制作了一个带有
插值
函数的模块,一个插值
类,并尝试了一个类似于该函数的插值
类方法
它有一个小的测试套件和它的文档
我被方法实现卡住了,我不明白
代码如下:
你们觉得呢,伙计们
[编辑03]:好的,我现在只使用
interpolate()
函数
在string\u 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]: 这是我的上一个版本,它有一个测试docstrings,并描述了我发现的一些限制: 您可以在此处快速测试代码: 并在此处克隆grom git repo:
中突出显示了问题的一部分,也就是它不起作用的原因 您可以通过将
globals()
作为第二个参数mprint('Hello my name is{name}',globals())
传入函数来工作
虽然Ruby可能很方便,但如果您想充分利用Python语言,我建议您不要用Python编写Ruby。模块在Python中不共享名称空间,因此
globals()
formy_print
始终是my_print.py文件的globals()
;i、 e实际定义函数的位置
def mprint(string='', dic = None):
dictionary = dic if dic is not None else globals()
print string.format(**dictionary)
您应该显式地传递当前模块的globals(),以使其工作
Ans在python函数中不使用可变对象作为默认值,这可能会导致错误。改用None
作为默认值
了解模块中作用域的一个简单示例:
文件: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
语言设计不仅仅是解决难题:
;)代码>
编辑:解决了这个问题
来自string
模块的Template
类也做了我需要的事情(但更类似于stringformat
方法),最后它还具有我所寻求的可读性,它还具有推荐的明确性,它位于标准库中,并且可以轻松地进行定制和扩展
有趣的是,现在我越来越喜欢使用{}
而不是$
,而且我仍然喜欢我提出的string\u interpolation
模块,因为从长远来看,它比任何一个模块都少打字。哈哈
在此处运行代码:
我只想少打字我开始在我的脚本中大量使用成语'.format(**vars())
,然后我意识到我必须重构它,所以我做了(尝试了),我真的不在乎它看起来是否像ruby,因为我直到最近才知道任何编程知识,但它对我来说仍然更具可读性,我经常使用它进行简单的格式化。我希望能够这样称呼它:从我的打印导入mprint;名称='Ismael';mprint(‘你好!我的名字是{name}’)
没有globals,etc每次都打电话来,只是想知道怎么做,一定有办法!基本上,我想要实现的是将其作为默认行为:mprint('Hello my name is{name}',vars())
而不每次显式调用vars()。谢谢你的链接!是否有一种方法可以将main.py
的名称空间从,my_print.py
获取为dict?我现在正在读关于继承的书,一个类点符号不会起作用吗?但那我就得让这个班可以打电话了?哈哈,我现在就到此为止,谢谢阿什维尼!从python文档:所以我需要从mprint内部获取main.py\uuuu dict\uuuu
,这真的不可能吗?我无法停止思考这个问题。@user2374329您可以使用main.\uu dict\uuu
,但它只包含导入main
时定义的变量。顺便说一句,继承与类而不是模块有关。再次感谢,我完全迷路了。相关:相关:这是一个有趣的练习,但我要警告这种隐式行为:Python不鼓励它(“显式优于隐式”在这里意味着mprint(“…”,vars())
优于mprint(“…”)
返回调用者并获取其局部变量),我认为这样做是有充分理由的(显式代码可以说更易于阅读和修改)
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())