理解Python数据类
最近在Python 3.7 中添加了DataClasses作为存储数据的实用工具。 DataClasses 提供了一个装饰器和函数,用于将生成的特殊方法(例如 __init__() 、 __repr__() 和 __eq__() )自动添加到用户定义的类中。
Python中的数据类
DataClasses就像Python中的普通类,但它们具有一些基本功能,例如实例化、比较和打印已经实现的类。
安装DataClasses 模块:
pip install dataclasses
数据类的语法是:
Syntax: @dataclasses.dataclass(*, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False)
Parameters:
- init: If true __init__() method will be generated
- repr: If true __repr__() method will be generated
- eq: If true __eq__() method will be generated
- order: If true __lt__(), __le__(), __gt__(), and __ge__() methods will be generated.
- unsafe_hash: If False __hash__() method is generated according to how eq and frozen are set
- frozen: If true assigning to fields will generate an exception.
DataClass 模块提供了一种使类不那么冗长的简便方法。让我们看看不使用 DataClass 的传统方法。
Python3
# creating a employee class
class employee:
# init method or constructor
def __init__(self, name, emp_id, age, city):
# Instance Variable
self.name = name
self.emp_id = emp_id
self.age = age
self.city = city
# magic function to return class object
def __repr__(self):
return ("employee (name={}, emp_id={}, age={}, city={} )"
.format(self.name, self.emp_id, self.age, self.city))
# magic function to return boolean
def __eq__(self, check):
return ((self.name, self.emp_id, self.age, self.city) ==
((check.name, check.emp_id, check.age, check.city)))
# initialization the object
emp1 = employee("Satyam", "ksatyam858", 21, 'Patna')
emp2 = employee("Anurag", "au23", 28, 'Delhi')
emp3 = employee("Satyam", "ksatyam858", 21, 'Patna')
print("employee object are :")
print(emp1)
print(emp2)
print(emp3)
# printing new line
print()
# referring two object to check equality
print("Data in emp1 and emp2 are same? ", emp1 == emp2)
print("Data in emp1 and emp3 are same? ", emp1 == emp3)
Python3
# A basic Data Class
# importing dataclass module
from dataclasses import dataclass
# A class for holding an employees content
@dataclass
class employee:
# Attributes Declaration
# using Type Hints
name: str
emp_id: str
age: int
city: str
emp1 = employee("Satyam", "ksatyam858", 21, 'Patna')
emp2 = employee("Anurag", "au23", 28, 'Delhi')
emp3 = employee("Satyam", "ksatyam858", 21, 'Patna')
print("employee object are :")
print(emp1)
print(emp2)
print(emp3)
# printing new line
print()
# referring two object to check equality
print("Data in emp1 and emp2 are same? ", emp1 == emp2)
print("Data in emp1 and emp3 are same? ", emp1 == emp3)
Python3
from dataclasses import dataclass
# A class for holding an employees content
@dataclass
class employee:
# Attributes Declaration
# using Type Hints
name: str
emp_id: str
age: int
city: str
# object of the class
emp = employee("Satyam", "ksatyam858", 21, 'Patna')
emp.__dataclass_fields__
Python3
# default field example
from dataclasses import dataclass, field
# A class for holding an employees content
@dataclass
class employee:
# Attributes Declaration
# using Type Hints
name: str
emp_id: str
age: int
# default field set
# city : str = "patna"
city: str = field(default="patna")
emp = employee("Satyam", "ksatyam858", 21)
print(emp)
Python3
# default factory example
from dataclasses import dataclass, field
def get_emp_id():
id = 2345
return id
# A class for holding an employees content
@dataclass
class employee:
# Attributes Declaration
# using Type Hints
name: str
age: int
# default factory field
emp_id: str = field(default_factory=get_emp_id)
city: str = field(default="patna")
# object of dataclass
emp = employee("Satyam", 21)
print(emp)
Python3
# init field example
from dataclasses import dataclass, field
# A class for holding an employees content
@dataclass
class employee:
# Attributes Declaration
# using Type Hints
name: str
age: int
# init field
emp_id: str
city: str = field(init=False, default="patna")
# object of dataclass
emp = employee("Satyam", "ksatyam858", 21)
print(emp)
Python3
# repr field
from dataclasses import dataclass, field
# A class for holding an employees content
@dataclass
class employee:
# Attributes Declaration
# using Type Hints
name: str
age: int
emp_id: str
city: str = field(init=False, default="patna", repr=True)
emp = employee("Satyam", 21, "ksatyam858"),
print(emp)
Python3
city: str = field(init=False, default="patna", repr=False)
emp = employee("Satyam", 21, "ksatyam858"),
emp
Python3
# hash
from dataclasses import dataclass, field
# A class for holding an employees content
@dataclass(unsafe_hash=True)
class employee:
# Attributes Declaration
# using Type Hints
name: str
age: int
emp_id: str = field(default_factory=get_emp_id)
city: str = field(init=False, default="patna", repr=True, hash=True)
emp = employee("Satyam", "ksatyam858", 21)
hash(emp)
Python3
city: str = field(init=False, default="patna", repr=True, hash=False)
# object of the class
emp = employee("Satyam", "ksatyam858", 21)
hash(emp)
Python3
# hash
from dataclasses import dataclass, field
# A class for holding an employees content
@dataclass(unsafe_hash=True)
class employee:
# Attributes Declaration
# using Type Hints
name: str
age: int
emp_id: str
city: str = field(init=False, default="patna",
repr=True, hash=False, compare=True)
emp1 = employee("Satyam", "ksatyam858", 21)
emp2 = employee("Kumar", "satyam.10151", 22)
emp1 == emp2
Python3
# hash
from dataclasses import dataclass, field
# A class for holding an employees content
@dataclass(unsafe_hash=True)
class employee:
# Attributes Declaration
# using Type Hints
name: str
age: int
emp_id: str
city: str = field(init=False, default="patna", repr=True,
metadata={'format': 'State'})
emp = employee("Satyam", "ksatyam858", 21)
emp.__dataclass_fields__['city'].metadata['format']
Python3
# A basic Data Class
# importing dataclass module
from dataclasses import dataclass, field
# A class for holding an employees content
@dataclass
class employee:
# Attributes Declaration
# using Type Hints
name: str
emp_id: str
age: int
city: str
# post init function
def __post_init__(self):
if self.age >= 30:
self.check_age = True
else:
self.check_age = False
emp = employee("Satyam", "ksatyam858", 21, 'Patna')
emp.check_age
Python3
# A basic Data Class
# importing dataclass module
from dataclasses import dataclass, field
# parent class
@dataclass
class Staff:
name: str
emp_id: str
age: int
# child class
@dataclass
class employee(Staff):
salary: int
emp = employee("Satyam", "ksatyam858", 21, 60000)
emp
employee object are :
employee (name=Satyam, emp_id=ksatyam858, age=21, city=Patna )
employee (name=Anurag, emp_id=au23, age=28, city=Delhi )
employee (name=Satyam, emp_id=ksatyam858, age=21, city=Patna )
Data in emp1 and emp2 are same? False
Data in emp1 and emp3 are same? True
在上面的代码中,最大的问题是在 __init__、__repr__ 和 __eq__ 中传递参数。每次它都必须复制其属性并返回对象。这是处理少量数据的好方法,但假设我们处理大数据。它使您的代码更加复杂。所以,这就是为什么 DataClass 将实现使您的代码更容易和方便。
这是在Python DataClasses中实现的相同示例。
蟒蛇3
# A basic Data Class
# importing dataclass module
from dataclasses import dataclass
# A class for holding an employees content
@dataclass
class employee:
# Attributes Declaration
# using Type Hints
name: str
emp_id: str
age: int
city: str
emp1 = employee("Satyam", "ksatyam858", 21, 'Patna')
emp2 = employee("Anurag", "au23", 28, 'Delhi')
emp3 = employee("Satyam", "ksatyam858", 21, 'Patna')
print("employee object are :")
print(emp1)
print(emp2)
print(emp3)
# printing new line
print()
# referring two object to check equality
print("Data in emp1 and emp2 are same? ", emp1 == emp2)
print("Data in emp1 and emp3 are same? ", emp1 == emp3)
输出:
employee object are :
employee(name=’Satyam’, emp_id=’ksatyam858′, age=21, city=’Patna’)
employee(name=’Anurag’, emp_id=’au23′, age=28, city=’Delhi’)
employee(name=’Satyam’, emp_id=’ksatyam858′, age=21, city=’Patna’)
Data in emp1 and emp2 are same? False
Data in emp1 and emp3 are same? True
在上面的代码中,我们不需要为 __init__、__repr__ 和 __eq__函数编写代码。
数据类.Field()
field() 对象描述了每个定义的字段。
Syntax: dataclasses.field(*, default=MISSING, default_factory=MISSING, repr=True, hash=None, init=True, compare=True, metadata=None)
Parameters:
- default
- default_factory
- init
- repr
- hash
- compare
- metadata
示例:演示如何查看数据类对象的字段。
蟒蛇3
from dataclasses import dataclass
# A class for holding an employees content
@dataclass
class employee:
# Attributes Declaration
# using Type Hints
name: str
emp_id: str
age: int
city: str
# object of the class
emp = employee("Satyam", "ksatyam858", 21, 'Patna')
emp.__dataclass_fields__
输出:
参数说明:
- default:该字段用于指定该字段的默认值。
蟒蛇3
# default field example
from dataclasses import dataclass, field
# A class for holding an employees content
@dataclass
class employee:
# Attributes Declaration
# using Type Hints
name: str
emp_id: str
age: int
# default field set
# city : str = "patna"
city: str = field(default="patna")
emp = employee("Satyam", "ksatyam858", 21)
print(emp)
输出:
employee(name=’Satyam’, emp_id=’ksatyam858′, age=21, city=’patna’)
- default_factory:该字段接受一个函数并返回该字段的初始值,它必须是一个零参数。
蟒蛇3
# default factory example
from dataclasses import dataclass, field
def get_emp_id():
id = 2345
return id
# A class for holding an employees content
@dataclass
class employee:
# Attributes Declaration
# using Type Hints
name: str
age: int
# default factory field
emp_id: str = field(default_factory=get_emp_id)
city: str = field(default="patna")
# object of dataclass
emp = employee("Satyam", 21)
print(emp)
输出:
employee(name=’Satyam’, age=21, emp_id=2345, city=’patna’)
- init :如果为 true,则此字段将作为参数包含在生成的 __init__() 方法中。
蟒蛇3
# init field example
from dataclasses import dataclass, field
# A class for holding an employees content
@dataclass
class employee:
# Attributes Declaration
# using Type Hints
name: str
age: int
# init field
emp_id: str
city: str = field(init=False, default="patna")
# object of dataclass
emp = employee("Satyam", "ksatyam858", 21)
print(emp)
输出:
employee(name=’Satyam’, age=’ksatyam858′, emp_id=21, city=’patna’)
- repr:如果为 true(默认值),则此字段包含在生成的 __repr__() 方法返回的字符串中。
蟒蛇3
# repr field
from dataclasses import dataclass, field
# A class for holding an employees content
@dataclass
class employee:
# Attributes Declaration
# using Type Hints
name: str
age: int
emp_id: str
city: str = field(init=False, default="patna", repr=True)
emp = employee("Satyam", 21, "ksatyam858"),
print(emp)
输出:
employee(name=’Satyam’, age=21, emp_id=’ksatyam858′, city=’patna’)
如果 repr 为假,则:
蟒蛇3
city: str = field(init=False, default="patna", repr=False)
emp = employee("Satyam", 21, "ksatyam858"),
emp
输出:
employee(name='Satyam', age=21, emp_id='ksatyam858')
- hash:如果为 true,则该字段包含在生成的 __hash__() 方法中。
蟒蛇3
# hash
from dataclasses import dataclass, field
# A class for holding an employees content
@dataclass(unsafe_hash=True)
class employee:
# Attributes Declaration
# using Type Hints
name: str
age: int
emp_id: str = field(default_factory=get_emp_id)
city: str = field(init=False, default="patna", repr=True, hash=True)
emp = employee("Satyam", "ksatyam858", 21)
hash(emp)
输出:
28166796391311520
如果为 false,则不会考虑这些字段。
蟒蛇3
city: str = field(init=False, default="patna", repr=True, hash=False)
# object of the class
emp = employee("Satyam", "ksatyam858", 21)
hash(emp)
输出:
6124029366977666702
- compare:如果为 true(默认值),则此字段包含在生成的相等和比较方法(__eq__()、__gt__() 中)。
蟒蛇3
# hash
from dataclasses import dataclass, field
# A class for holding an employees content
@dataclass(unsafe_hash=True)
class employee:
# Attributes Declaration
# using Type Hints
name: str
age: int
emp_id: str
city: str = field(init=False, default="patna",
repr=True, hash=False, compare=True)
emp1 = employee("Satyam", "ksatyam858", 21)
emp2 = employee("Kumar", "satyam.10151", 22)
emp1 == emp2
输出:
False
- 元数据:这可以是映射或无。 None 被视为空字典。
蟒蛇3
# hash
from dataclasses import dataclass, field
# A class for holding an employees content
@dataclass(unsafe_hash=True)
class employee:
# Attributes Declaration
# using Type Hints
name: str
age: int
emp_id: str
city: str = field(init=False, default="patna", repr=True,
metadata={'format': 'State'})
emp = employee("Satyam", "ksatyam858", 21)
emp.__dataclass_fields__['city'].metadata['format']
初始化后处理
在创建对象时自动调用 __post_init__() 方法。 __init__() 代码将调用名为 __post_init__() 的方法。
示例:在一个员工数据类中,如果我们想检查员工年龄,那么我们可以定义到 __post_init__() 方法中。
蟒蛇3
# A basic Data Class
# importing dataclass module
from dataclasses import dataclass, field
# A class for holding an employees content
@dataclass
class employee:
# Attributes Declaration
# using Type Hints
name: str
emp_id: str
age: int
city: str
# post init function
def __post_init__(self):
if self.age >= 30:
self.check_age = True
else:
self.check_age = False
emp = employee("Satyam", "ksatyam858", 21, 'Patna')
emp.check_age
输出:
False
数据类继承
继承使我们能够定义一个类,该类从父类中获取所有功能。
示例:子类继承父类的属性。
蟒蛇3
# A basic Data Class
# importing dataclass module
from dataclasses import dataclass, field
# parent class
@dataclass
class Staff:
name: str
emp_id: str
age: int
# child class
@dataclass
class employee(Staff):
salary: int
emp = employee("Satyam", "ksatyam858", 21, 60000)
emp
输出:
employee(name='Satyam', emp_id='ksatyam858', age=21, salary=60000)