Python3的一些新特性
发表于更新于
字数总计:1.3k阅读时长:5分钟阅读量: 长沙
下面的内容在py3.8测试ok,有些是3.5或者3.7之后才开放的特性
语句变成函数
print
语句在python3里变成了print()
函数。
1 2 3 4 5 6 7
| print 'hello pig!'
print('hello pig') print('1', '2', '3', sep='+') print('1', '2', '3', sep='\n')
|
raise
语句。
1 2 3 4 5
| raise Exception, 'I made a mistake.'
raise Exception('I made a mistake.')
|
当然还有exec()
。
1 2 3 4 5
| exec 'print("Hello World")'
exec('print("Hello World")')
|
除法
python2中/
的结果是整型,python3中是浮点类型。
1 2 3 4 5 6 7
| print 10/2 >>> 5
print(10/2) >>> 5.0
|
允许数值下划线
为了提高多位数字的可读性,可以这样写:
1 2
| a = 1_000_000_000_000 b = 0x_FF_FF_FF_FF
|
字典保持顺序
现在的字典是有序的了,不需要再调用collections.OrderedDict
来生成有序字典了。
类似迭代器的返回值
在python3中,之前返回列表的内置函数,比如map
,range
,zip
,filter
等等。
它们的返回值都变成了类似迭代器的对象。(这种懒加载方式为了性能考虑)
这里以map来举例:
1 2 3 4 5 6 7
| map(sum, ((1, 2), (3, 4), (5, 6))) >>> [3, 7, 11]
map(sum, ((1, 2), (3, 4), (5, 6))) >>> <map at 0x7ff2989a0910>
|
注意:字典里的dict.keys()
,dict.values()
,dict.items()
在python3里也不会返回列表了,
同样返回的是一个类似迭代器的对象。(字典的dict.iteritems()
方法没有了)
except语句
except
语句的轻微改变,
捕获异常必须使用except...as...
的格式。
1 2 3 4 5 6 7 8 9 10 11
| try: 1/0 except ZeroDivisionError, e: print e
try: 1/0 except ZeroDivisionError as e: print(e)
|
赋值表达式
优点是可以防止多次计算重复值和可以写赋值表达式。
(其实就是为了少写一行,有点鸡肋的特性)
比如这样一段代码:
1 2 3 4 5 6 7 8 9
| import re
data = "check123out" match = re.search("(\d+)", data) if match: num = match.group(1) else: num = None print(num)
|
使用赋值表达式:
1 2 3 4 5 6 7 8 9
| import re
data = "check123out"
if match := re.search("(\d+)", data): num = match.group(1) else: num = None print(num)
|
类型标注
比如声明一个函数时,标注其参数和返回值的类型。
注意:它只起到标注作用(增加代码可读性),python并不会真的限制其类型。
一个简单的例子:
1 2 3 4 5
| def greeting(name: str) -> str: return 'Hello ' + name
def plus(a: int, b: int = 2) -> int: return a + b
|
类型标准支持别名,可以用它来简化一些复杂的类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| from typing import Dict, Tuple, Sequence
def broadcast_message( message: str, servers: Sequence[Tuple[Tuple[str, int], Dict[str, str]]]) -> None: pass
ConnectionOptions = Dict[str, str] Address = Tuple[str, int] Server = Tuple[Address, ConnectionOptions]
def broadcast_message(message: str, servers: Sequence[Server]) -> None: pass
|
当然万物皆是对象的python,函数也可以成为其标注的对象。
1 2 3 4 5 6
| from typing import Callable
def get_regex() -> Callable[[str, str], bool]: def regex(pattern: str, string: str) -> bool: return re return regex()
|
变量也可以标注类型,这样就可以先声明类型,再进行赋值。
在python3.7后,我们可以使用dataclass来简化声明类的时,标记类型的写法。
(这是真好用!)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| from typing import Tuple
class Bar: def __init__( self, name: str, phone: int, location: Tuple[float, float] ): self.name = name self.phone = phone self.location = location
from dataclasses import dataclass from typing import Tuple
class Bar(dataclass): name: str phone: int location: Tuple[float, float]
|
参考:https://www.python.org/dev/peps/pep-0484/
格式化字符串
可以不用format
了!
一个简单的用法:
1 2 3 4
| name = "Han Meimei" print(f"My name is {name}.")
>>> My name is Han Meimei.
|
支持函数。
1 2 3 4 5
| def foo(): return 20
print(f'result={foo()}') >>> result=20
|
可以用做十进制转换。
1 2 3
| value = 1234 f'input={value:#06x}' >>> 'input=0x04d2'
|
用来格式化日期
1 2 3
| date = datetime.date(1991, 10, 12) print(f'{date} was on a {date:%A}') >>> '1991-10-12 was on a Saturday'
|
还可以这样嵌套来限制字符宽度和数字的长度。
1 2 3 4 5 6 7
| import decimal
width = 10 precision = 4 value = decimal.Decimal('12.34567') print(f'result: {value:{width}.{precision}}') >>> result: 12.35
|
支持=
符号,来打印可读性的输出:
1 2 3 4 5 6
| pos_x = 1.0 pos_y = 2.0 pos_z = 3.0
print(f'The xyz value: {pos_x=} {pos_y=} {pos_z=}') >>> The xyz value: pos_x=1.0 pos_y=2.0 pos_z=3.0
|
参考:https://www.python.org/dev/peps/pep-0498/
虚拟变量
在python2中,运行下面的代码,变量i是会被打印出来的。
1 2 3
| a = [i for i in range(10)] print(i) >>> 9
|
而在python3中就会触发错误:NameError: name 'i' is not defined
断点调试
之前设置断点都是通过诸如pycharm之类的IDE来设置。
在python3.6之前,也许会使用import pdb; pdb.set_trace()
。
现在可以在代码里通过函数breakpoint()
来设置断点。
比如下面这段会导致ZeroDivisionError
代码:
1 2 3 4 5
| def divide(e, f): return f / e
a, b = 2, 1 print(divide(a, b))
|
添加breakpoint()
函数。
1 2 3 4 5 6
| def divide(e, f): breakpoint() return f / e
a, b = 2, 1 print(divide(a, b))
|
当调试完成后,可以注释掉所有的breakpoint()
代码,也可以设置环境变量PYTHONBREAKPOINT
为0,python将会忽略所有breakpoint()
的调用。
模块重载
python3中的reload被替换成了:
1 2 3
| import spam import imp imp.reload(spam)
|