前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >将特性与Mixin类混合

将特性与Mixin类混合

作者头像
公众号---人生代码
发布2020-05-19 20:15:16
5700
发布2020-05-19 20:15:16
举报
文章被收录于专栏:人生代码人生代码

python中多重继承的用途之一是通过mixins扩展类功能。mixin是提供其他类方法的类,但不被视为基类

mixin允许其他类重用它的接口和实现,而不必成为超类。它们实现了一种独特的行为,这种行为可以聚合到其他不相关的类中。它们类似于构成,但它们创建了更强的关系

假设您希望将应用程序中某些类型的对象转换为对象的字典表示形式。您可以在希望支持此功能的每个类中提供.to_dict()方法,但是.to_dict()的实现似乎非常类似

这可能是混入的很好的候选人。首先,从构成示例中稍微修改Employee类

代码语言:python
复制
# In employees.py

class Employee:
    def __init__(self, id, name, address, role, payroll):
        self.id = id
        self.name = name
        self.address = address
        self._role = role
        self._payroll = payroll


    def work(self, hours):
        duties = self._role.perform_duties(hours)
        print(f'Employee {self.id} - {self.name}:')
        print(f'- {duties}')
        print('')
        self._payroll.track_work(hours)

    def calculate_payroll(self):
        return self._payroll.calculate_payroll()

变化很小。您只需在角色和工资单属性的名称上添加一个下划线,即可将其更改为内部属性。您很快就会知道为什么要进行更改

现在,您添加AsDictionaryMixin类

代码语言:python
复制
# In representations.py

class AsDictionaryMixin:
    def to_dict(self):
        return {
            prop: self._represent(value)
            for prop, value in self.__dict__.items()
            if not self._is_internal(prop)
        }

    def _represent(self, value):
        if isinstance(value, object):
            if hasattr(value, 'to_dict'):
                return value.to_dict()
            else:
                return str(value)
        else:
            return value

    def _is_internal(self, prop):
        return prop.startswith('_')

AsDictionaryMixin类公开了一个.to_dict()方法,该方法将自身的表示形式作为字典返回。这个方法是作为一个dict理解来实现的,它说,“如果这个道具不是内部的,那么为self.__dict__.items()中的每一项创建一个映射道具到值的字典。”

正如您在开始时看到的,创建一个类从object继承了一些成员,其中一个成员是__dict__,它基本上是一个对象中所有属性到它们的值的映射

代码语言:python
复制
# In employees.py

from representations import AsDictionaryMixin

class Employee(AsDictionaryMixin):
    def __init__(self, id, name, address, role, payroll):
        self.id = id
        self.name = name
        self.address = address
        self._role = role
        self._payroll = payroll

    def work(self, hours):
        duties = self._role.perform_duties(hours)
        print(f'Employee {self.id} - {self.name}:')
        print(f'- {duties}')
        print('')
        self._payroll.track_work(hours)

    def calculate_payroll(self):
        return self._payroll.calculate_payroll()

您所要做的就是继承AsDictionaryMixin以支持该功能。最好在Address类中支持相同的功能,因此Employee.address属性以相同的方式表示

代码语言:python
复制
# In contacts.py

from representations import AsDictionaryMixin

class Address(AsDictionaryMixin):
    def __init__(self, street, city, state, zipcode, street2=''):
        self.street = street
        self.street2 = street2
        self.city = city
        self.state = state
        self.zipcode = zipcode

    def __str__(self):
        lines = [self.street]
        if self.street2:
            lines.append(self.street2)
        lines.append(f'{self.city}, {self.state} {self.zipcode}')
        return '\n'.join(lines)

您将mixin应用于Address类以支持该功能。现在,您可以编写一个小程序进行测试

代码语言:python
复制
# In program.py

 import json
 from employees import EmployeeDatabase

 def print_dict(d):
    print(json.dumps(d, indent=2))

for employee in EmployeeDatabase().employees:
    print_dict(employee.to_dict())

该程序实现了print_dict(),它使用缩进将字典转换为JSON字符串,因此输出看起来更好

然后,遍历所有员工,打印.to_dict()提供的字典表示形式。您可以运行该程序以查看其输出

代码语言:shell
复制
$ python program.py

 {
  "id": "1",
  "name": "Mary Poppins",
  "address": {
    "street": "121 Admin Rd.",
    "street2": "",
    "city": "Concord",
    "state": "NH",
    "zipcode": "03301"
  }
}
{
  "id": "2",
  "name": "John Smith",
  "address": {
    "street": "67 Paperwork Ave",
    "street2": "",
    "city": "Manchester",
    "state": "NH",
    "zipcode": "03101"
  }
}
{
  "id": "3",
  "name": "Kevin Bacon",
  "address": {
    "street": "15 Rose St",
    "street2": "Apt. B-1",
    "city": "Concord",
    "state": "NH",
    "zipcode": "03301"
  }
}
{
  "id": "4",
  "name": "Jane Doe",
  "address": {
    "street": "39 Sole St.",
    "street2": "",
    "city": "Concord",
    "state": "NH",
    "zipcode": "03301"
  }
}
{
  "id": "5",
  "name": "Robin Williams",
  "address": {
    "street": "99 Mountain Rd.",
    "street2": "",
    "city": "Concord",
    "state": "NH",
    "zipcode": "03301"
  }
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CryptoCode 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档