本文摘自php中文网,作者不言,侵删。
这篇文章主要给大家介绍了关于Python 3.7新功能之dataclass装饰器的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们一起学习学习吧。
前言
Python 3.7 将于今年夏天发布,Python 3.7 中将会有许多新东西:
各种字符集的改进
对注释的推迟评估
以及对dataclass的支持
最激动人心的新功能之一是 dataclass 装饰器。
什么是 Data Class
大多数 Python 开发人员编写过很多像下面这样的类:
1
2
3
4
class
MyClass:
def
__init__(
self
, var_a, var_b):
self
.var_a
=
var_a
self
.var_b
=
var_b
dataclass 可以为简单的情况自动生成方法,例如,一个__init__接受这些参数并将其分配给自己,之前的小例子可以重写为:
1
2
3
4
@dataclass
class
MyClass:
var_a:
str
var_b:
str
那么通过一个例子来看看如何使用吧
星球大战 API
可以使用 requests 从星球大战 API 获取资源:
1
2
response
=
requests.get(
'https://swapi.co/api/films/1/'
)
dictionary
=
response.json()
让我们来看看 dictionary (简化过)的结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
'characters'
: [
'https://swapi.co/api/people/1/'
,… ],
'created'
:
'2014-12-10T14:23:31.880000Z'
,
'director'
:
'George Lucas'
,
'edited'
:
'2015-04-11T09:46:52.774897Z'
,
'episode_id'
:
4
,
'opening_crawl'
:
'It is a period of civil war.\r\n … '
,
'planets'
: [
'https://swapi.co/api/planets/2/'
, … ],
'producer'
:
'Gary Kurtz, Rick McCallum'
,
'release_date'
:
'1977-05-25'
,
'species'
: [
'https://swapi.co/api/species/5/'
,…],
'starships'
: [
'https://swapi.co/api/starships/2/'
,…],
'title'
:
'A New Hope'
,
'url'
:
'https://swapi.co/api/films/1/'
,
'vehicles'
: [
'https://swapi.co/api/vehicles/4/'
,…]
封装 API
为了正确地封装一个 API,我们应该创建一个用户可以在其应用程序中使用的对象,因此,在Python 3.6 中定义一个对象来包含requests对 /films/endpoint的响应:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class
StarWarsMovie:
def
__init__(
self
,
title:
str
,
episode_id:
int
,
opening_crawl:
str
,
director:
str
,
producer:
str
,
release_date: datetime,
characters:
List
[
str
],
planets:
List
[
str
],
starships:
List
[
str
],
vehicles:
List
[
str
],
species:
List
[
str
],
created: datetime,
edited: datetime,
url:
str
):
self
.title
=
title
self
.episode_id
=
episode_id
self
.opening_crawl
=
opening_crawl
self
.director
=
director
self
.producer
=
producer
self
.release_date
=
release_date
self
.characters
=
characters
self
.planets
=
planets
self
.starships
=
starships
self
.vehicles
=
vehicles
self
.species
=
species
self
.created
=
created
self
.edited
=
edited
self
.url
=
url
if
type
(
self
.release_date)
is
str
:
self
.release_date
=
dateutil.parser.parse(
self
.release_date)
if
type
(
self
.created)
is
str
:
self
.created
=
dateutil.parser.parse(
self
.created)
if
type
(
self
.edited)
is
str
:
self
.edited
=
dateutil.parser.parse(
self
.edited)
仔细的读者可能已经注意到这里有一些重复的代码。
这是使用 dataclass 装饰器的经典案例,我们需要创建一个主要用来保存数据的类,只需一点验证,所以让我们来看看我们需要修改什么。
首先,data class 自动生成一些 dunder 方法,如果我们没有为 data class 装饰器指定任何选项,则生成的方法有:__init__,__eq__和__repr__,如果你已经定义了__repr__但没定义__str__,默认情况下 Python(不仅仅是 data class)将实现返回__repr__的输出__str__方法。因此,只需将代码更改为以下代码即可实现四种 dunder 方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@dataclass
class
StarWarsMovie:
title:
str
episode_id:
int
opening_crawl:
str
director:
str
producer:
str
release_date: datetime
characters:
List
[
str
]
planets:
List
[
str
]
starships:
List
[
str
]
vehicles:
List
[
str
]
species:
List
[
str
]
created: datetime
edited: datetime
url:
str
我们去掉了__init__方法,以确保 data class 装饰器可以添加它生成的对应方法。不过,我们在这个过程中失去了一些功能,我们的 Python 3.6 构造函数不仅定义了所有的值,还试图解析日期,我们怎样才能用 data class 来做到这一点呢?
如果要覆盖 __init__,我们将失去 data class 的优势,因此,如果要处理任何附加功能可以使用新的 dunder 方法:__post_init__,让我们看看__post_init__方法对于我们的包装类来说是什么样子的:
1
2
3
4
5
6
7
8
9
def
__post_init__(
self
):
if
type
(
self
.release_date)
is
str
:
self
.release_date
=
dateutil.parser.parse(
self
.release_date)
if
type
(
self
.created)
is
str
:
self
.created
=
dateutil.parser.parse(
self
.created)
if
type
(
self
.edited)
is
str
:
self
.edited
=
dateutil.parser.parse(
self
.edited)
就是这样! 我们可以使用 data class 装饰器在用三分之二的代码量实现我们的类。
更多好东西
通过使用装饰器的选项,可以为用例进一步定制 data class,默认选项是:
1
@dataclass
(init
=
True
,
repr
=
True
, eq
=
True
, order
=
False
, unsafe_hash
=
False
, frozen
=
False
)
init决定是否生成__init__ dunder 方法
repr决定是否生成__repr__ dunder方法
eq对__eq__ dunder 方法也是如此,它决定相等性检查的行为(your_class_instance == another_instance)
order 实际上创建了四种 dunder 方法,它们确定所有检查小于,and/or,大于的行为,如果将其设置为 true,则可以对对象列表进行排序。
最后两个选项确定对象是否可以被哈希化,如果你想使用你的 class 的对象作为字典键的话,这是必要的。
更多信息请参考:PEP 557 -- Data Classes
以上就是Python 3.7新功能之dataclass装饰器详解的详细内容,更多文章请关注木庄网络博客 !!
相关阅读 >>
使用xcode怎么编写并运行Python ?
Python 中re模块与正则表达式的介绍(附代码)
Python 基础知识之二:网络通信数据传输
Python 中str相关操作讲解
学习在Python 中实现自动导入缺失的库
Python 之post登录实例代码
Python 怎么输入数组
string在Python 中是什么意思
如何使用Python 读取excel文件?(代码示例)
Python 基础学完了学什么
更多相关阅读请进入《Python 》频道 >>
¥69.8元 人民邮电出版社
python入门书籍,非常畅销,超高好评,python官方公认好书。
转载请注明出处:木庄网络博客 » Python 3.7新功能之dataclass装饰器详解