Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我可以导入Python';s 3.6';将格式化的字符串文本(f字符串)转换为旧的3.x、2.x Python?_Python_String_F String - Fatal编程技术网

我可以导入Python';s 3.6';将格式化的字符串文本(f字符串)转换为旧的3.x、2.x Python?

我可以导入Python';s 3.6';将格式化的字符串文本(f字符串)转换为旧的3.x、2.x Python?,python,string,f-string,Python,String,F String,新的Python3.6f-strings对我来说似乎是字符串可用性的一个巨大飞跃,我很乐意在新项目中全身心地采用它们,这些项目可能会在旧的解释器上运行。2.7、3.3-3.5支持将非常好,但至少我希望在Python 3.5代码库中使用这些支持。如何导入3.6的格式化字符串文字供较老的解释器使用 我知道像f“Foo is{age}{units}old”这样的格式化字符串文本不会破坏更改,因此不会包含在来自{uuuuu future\uuuuu import…调用的中。但是更改不是后端口的(AFAI

新的Python3.6f-strings对我来说似乎是字符串可用性的一个巨大飞跃,我很乐意在新项目中全身心地采用它们,这些项目可能会在旧的解释器上运行。2.7、3.3-3.5支持将非常好,但至少我希望在Python 3.5代码库中使用这些支持。如何导入3.6的格式化字符串文字供较老的解释器使用


我知道像
f“Foo is{age}{units}old”
这样的格式化字符串文本不会破坏更改,因此不会包含在来自{uuuuu future\uuuuu import…调用的
中。但是更改不是后端口的(AFAIK),我需要确保我用f字符串编写的任何新代码都只在Python3.6+上运行,这对于很多项目来说都是一个破坏者。

不幸的是,如果你想使用它,你必须要求
Python3.6+
,与矩阵乘法运算符
@
Python3.5+
相同,或者
中产生(
Python3.4+

这些更改了代码的解释方式,因此在旧版本中导入时会抛出语法错误。这意味着您需要将它们放在一个地方,使它们不会被旧python导入,也不会被
eval
exec
保护(我不推荐后两种!)


因此,是的,你是对的,如果你想支持多个python版本,你就不能轻松地使用它们。

f字符串是由解释器在标记
f
前缀时创建的-仅此功能就将扼杀任何兼容性机会

最接近的镜头是使用关键字格式,如

'Foo is {age} {units} old'.format(age=age, units=units)
在兼容性需求终止时,可以更容易地重构

将f字符串引入Python 2.7脚本。(根据文档,我假设为3.3-3.5。)

一旦您通过
pip install future fstrings
安装了它,您必须在代码顶部放置一个特殊的行。这条线是:

# -*- coding: future_fstrings -*-
然后,您可以在代码中使用格式化字符串文字(f字符串):

# -*- coding: future_fstrings -*-
var = 'f-string'
print(f'hello world, this is an {var}')
以下是我使用的:

text = "Foo is {age} {units} old".format(**locals())
它解压缩(
**
)由
locals()
返回的dict,该dict将所有局部变量作为dict
{variable\u name:value}

注意这不适用于在外部作用域中声明的变量,除非您使用
非本地
(Python 3.0+)将其导入本地作用域

你也可以使用

text.format(**locals(),**globals())

在字符串中包含全局变量。

我刚刚为f-string编写了一个后端编译器,名为。正如您所要求的,您可以在Python3.6flavor中编写f-string文本,并编译成一个兼容版本供最终用户运行,就像JavaScript一样

f2format
提供了一个智能但不完善的后端口编译器解决方案。它应使用
str.format
方法替换f字符串文字,同时保持源代码的原始布局。你可以简单地使用

f2format/path/to/the/file\u或\u目录

这将重写所有Python文件。比如说,

var=f'foo{(1+2)*3:>5}bar{“a”,“b”!r}boo'

将转换为

var=('foo{:>5}bar{!r}boo')。格式(((1+2)*3),(“a”,“b”)


字符串连接、转换、格式规范、多行和Unicode都被正确处理。此外,
f2format
将归档原始文件,以防出现语法漏洞。

使用
simpleeval的肮脏解决方案

import re
import simpleeval
test='_someString'
lst = ['_456']

s = '123123{lst[0]}{test}'

def template__format(template, context=None):
    if context is None:
        frame = inspect.currentframe()
        context = frame.f_back.f_locals        
        del frame
    ptn =  '([^{]?){([^}]+)}'
    class counter():
        i = -1

    def count(m):
        counter.i += 1
        return m.expand('\\1{%d}'%counter.i)

    template = re.sub(ptn,string=s, repl= count)
    exprs = [x[1] for x in re.findall(ptn,s)]
    vals = map(simpleeval.SimpleEval(names=context).eval,exprs)
    res = template.format(*vals)
    return res

print (template__format(s))


我使用
'str'.format(**locals())
已经有一段时间了,但过了一段时间之后,我才这样做,因为对于每个语句来说,额外的代码都有点麻烦

def f(string):
    """
    Poor man's f-string for older python versions
    """
    import inspect

    frame = inspect.currentframe().f_back

    v = dict(**frame.f_globals)
    v.update(**frame.f_locals)

    return string.format(string, **v)

# Example
GLOBAL = 123


def main():
    foo = 'foo'
    bar = 'bar'

    print(f('{foo} != {bar} - global is {GLOBAL}'))


if __name__ == '__main__':
    main()
使用dict()保存名称-值对
  • 除了本线程中其他地方提到的方法(例如
    format(**locals())
    ),开发人员还可以创建一个或多个python字典来保存名称-值对

  • 对于任何有经验的python开发人员来说,这是一种显而易见的方法,但是很少有讨论明确地列举这个选项,可能是因为这是一种显而易见的方法

  • 与不加选择地使用
    locals()
    相比,这种方法无疑是有利的,因为它不那么不加选择。它明确地使用一个或多个字典作为名称空间,用于格式化字符串

  • Python3还允许解包多个字典(例如,
    .format(**dict1,**dict2,**dict3)
    …这在Python2.7中不起作用)

##初始指令 ddvars=dict() ##指定固定值 ddvars['firname']='Huomer' ddvars['lasname']='Huimpson' ddvars['age']=33 通过 ##分配计算值 ddvars['comname']='{firname}{lasname}'。格式(**ddvars) ddvars['reprself']=repr(ddvars) ddvars['nextage']=ddvars['age']+1 通过 ##创建并显示示例消息 mymessage=''' 你好{firname}{lasname}! 今天你已经{age}岁了。 在你的下一个生日,你将是{nextage}岁! ''。格式(**ddvars) 打印(mymessage)
如果使用此方法,并假设年龄和单位已经是变量,那么将其写成
'Foo is{age}{units}old.格式(age=age,units=units)
用于python2.7,这样在移动到python3.6时,它就可以快速更新为
f'Foo is{age}{units}{old'
旧的“.format(**locals(),**globals())
?@MadPhysicast可以工作,但被认为形式不好,因为在format调用中包含了厨房水槽。@GringoSuave。同意,但这与实际f字串的计算方法非常接近。@Mad物理学家,不是真的,明确的设计目标是不这样做。字符串在编译时被解析为字符串和表达式部分,表达式部分是普通的 ## init dict ddvars = dict() ## assign fixed values ddvars['firname'] = 'Huomer' ddvars['lasname'] = 'Huimpson' ddvars['age'] = 33 pass ## assign computed values ddvars['comname'] = '{firname} {lasname}'.format(**ddvars) ddvars['reprself'] = repr(ddvars) ddvars['nextage'] = ddvars['age'] + 1 pass ## create and show a sample message mymessage = ''' Hello {firname} {lasname}! Today you are {age} years old. On your next birthday you will be {nextage} years old! '''.format(**ddvars) print(mymessage)