Python 3.8 有什么新变化 - 其他语言特性修改

其他语言特性修改

在之前版本中 continue 语句不允许在 finally 子句中使用,这是因为具体实现存在一个问题。 在 Python 3.8 中此限制已被取消。 (由 Serhiy Storchaka 在 bpo-32489 中贡献。)

bool, int 和 fractions.Fraction 类型现在都有一个 as_integer_ratio() 方法,与 float 和 decimal.Decimal 中的已有方法类似。 这个微小的 API 扩展使得 numerator, denominator = x.as_integer_ratio() 这样的写法在多种数字类型上通用成为可能。 (由 Lisa Roach 在 bpo-33073 和 Raymond Hettinger 在 bpo-37819 中贡献。)

int, float 和 complex 的构造器现在会使用 index() 特殊方法,如果该方法可用而对应的方法 method int(), float() 或 complex() 方法不可用的话。 (由 Serhiy Storchaka 在 bpo-20092 中贡献。)

添加 \N{name} 转义符在 正则表达式 中的支持:

>>>
>>> notice = 'Copyright © 2019'
>>> copyright_year_pattern = re.compile(r'\N{copyright sign}\s*(\d{4})')
>>> int(copyright_year_pattern.search(notice).group(1))
2019

(由 Jonathan Eunice 和 Serhiy Storchaka 在 bpo-30688 中贡献。)

现在 dict 和 dictview 可以使用 reversed() 按插入顺序反向迭代。 (由 Rémi Lapeyre 在 bpo-33462 中贡献。)

在函数调用中允许使用的关键字名称语法受到进一步的限制。 特别地,f((keyword)=arg) 不再被允许。 关键字参数赋值形式的左侧绝不允许一般标识符以外的其他内容。 (由 Benjamin Peterson 在 bpo-34641 中贡献。)

在 yield 和 return 语句中的一般可迭代对象解包不再要求加圆括号。 这使得 yield 和 return 的语法与正常的赋值语法更为一致:

>>>
>>> def parse(family):
        lastname, *members = family.split()
        return lastname.upper(), *members

>>> parse('simpsons homer marge bart lisa maggie')
('SIMPSONS', 'homer', 'marge', 'bart', 'lisa', 'maggie')

(由 David Cuthbert 和 Jordan Chapman 在 bpo-32117 中贡献。)

当类似 [(10, 20) (30, 40)] 这样在代码中少了一个逗号时,编译器将显示 SyntaxWarning 并附带更有帮助的提示。 这相比原来用 TypeError 来提示第一个元组是不可调用的更容易被理解。 (由 Serhiy Storchaka 在 bpo-15248 中贡献。)

datetime.date 或 datetime.datetime 和 datetime.timedelta 对象之间的算术运算现在将返回相应子类的实例而不是基类的实例。 这也会影响到在具体实现中(直接或间接地)使用了 datetime.timedelta 算术运算的返回类型,例如 astimezone()。 (由 Paul Ganssle 在 bpo-32417 中贡献。)

当 Python 解释器通过 Ctrl-C (SIGINT) 被中断并且所产生的 KeyboardInterrupt 异常未被捕获,Python 进程现在会通过一个 SIGINT 信号或是使得发起调用的进程能检测到它是由 Ctrl-C 操作杀死的正确退出代码来退出。 POSIX 和 Windows 上的终端会相应地使用此代码在交互式会话中终止脚本。 (由 Google 的 Gregory P. Smith 在 bpo-1054041 中贡献。)

某些高级编程风格要求为现有的函数更新 types.CodeType 对象。 由于代码对象是不可变的,需要基于现有代码对象模型创建一个新的代码对象。 使用 19 个形参将会相当繁琐。 现在,新的 replace() 方法使得通过少量修改的形参创建克隆对象成为可能。

下面是一个修改 statistics.mean() 函数来防止 data 形参被用作关键字参数的例子:

>>>
>>> from statistics import mean
>>> mean(data=[10, 20, 90])
40
>>> mean.__code__ = mean.__code__.replace(co_posonlyargcount=1)
>>> mean(data=[10, 20, 90])
Traceback (most recent call last):
  ...
TypeError: mean() got some positional-only arguments passed as keyword arguments: 'data'

(由 Victor Stinner 在 bpo-37032 中贡献。)

对于整数,现在 pow() 函数的三参数形式在底数与模数不可约的情况下允许指数为负值。 随后它会在指数为 -1 时计算底数的模乘逆元,并对其他负指数计算反模的适当幂次。 例如,要计算 38 模 137 的 模乘逆元 则可写为:

>>>
>>> pow(38, -1, 137)
119
>>> 119 * 38 % 137
1

模乘逆元在求解 线性丢番图方程 会被用到。 例如,想要求出 4258𝑥 + 147𝑦 = 369 的整数解,首先应重写为 4258𝑥 ≡ 369 (mod 147) 然后求解:

>>>
x = 369 * pow(4258, -1, 147) % 147
y = (4258 * x - 369) // -147
4258 * x + 147 * y
369

(由 Mark Dickinson 在 bpo-36027 中贡献。)

字典推导式已与字典字面值实现同步,会先计算键再计算值:

>>>
>>> # Dict comprehension
>>> cast = {input('role? '): input('actor? ') for i in range(2)}
role? King Arthur
actor? Chapman
role? Black Knight
actor? Cleese

>>> # Dict literal
>>> cast = {input('role? '): input('actor? ')}
role? Sir Robin
actor? Eric Idle

对执行顺序的保证对赋值表达式来说很有用,因为在键表达式中赋值的变量将可在值表达式中被使用:

>>>
>>> names = ['Martin von Löwis', 'Łukasz Langa', 'Walter Dörwald']
>>> {(n := normalize('NFC', name)).casefold() : n for name in names}
{'martin von löwis': 'Martin von Löwis',
 'łukasz langa': 'Łukasz Langa',
 'walter dörwald': 'Walter Dörwald'}

(由 Jörn Heissler 在 bpo-35224 中贡献。)

object.reduce() 方法现在可返回长度为二至六个元素的元组。 之前的上限为五个。 新增的第六个可选元素是签名为 (obj, state) 的可调用对象。 这样就允许直接控制特定对象的状态更新。 如果元素值不为 None,该可调用对象将优先于对象的 setstate() 方法。 (由 Pierre Glaser 和 Olivier Grisel 在 bpo-35900 中贡献。)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值