📜  理解Python数据类

📅  最后修改于: 2022-05-13 01:54:48.625000             🧑  作者: Mango

理解Python数据类

最近在Python 3.7 中添加了DataClasses作为存储数据的实用工具。 DataClasses 提供了一个装饰器和函数,用于将生成的特殊方法(例如 __init__() 、 __repr__() 和 __eq__() )自动添加到用户定义的类中。

Python中的数据类

DataClasses就像Python中的普通类,但它们具有一些基本功能,例如实例化、比较和打印已经实现的类。

安装DataClasses 模块:

pip install dataclasses

数据类的语法是:

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)

输出:

在上面的代码中,我们不需要为 __init__、__repr__ 和 __eq__函数编写代码。

数据类.Field()

field() 对象描述了每个定义的字段。

示例:演示如何查看数据类对象的字段。

蟒蛇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)

输出:

  • 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)

输出:

  • 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)

输出:

  • 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)

输出:

如果 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)