Python类和对象

  Python Cookbook第八章主要介绍了一些类定义的技巧,在此对感兴趣的一些内容进行记录。

简化数据的初始化

  可以通过定义一个通用基类来同一管理数据的初始化。

class Structure:
    _fields = []

    def __init__(self, *args):
        if len(args) != len(self._fields):
            raise TypeError('Excepted {} arguments'.format(len(self._fields)))

        for name, value in zip(self._fields, args):
            setattr(self, name, value)

使用如下:

class Stock(Structure):
    _fields = ['name', 'shares', 'price']

    def __str__(self):
        str_tmp = 'name:{}, shares:{}, price:{}'.format(self.name, self.shares, self.price)
        return str_tmp

tmp = Stock('hahaha', 1, 2)
print(tmp)

输入如下

name:hahaha, shares:1, price:2

创建一个可管理的属性

可以使用@property来创建属性,并对属性进行简单的管理

class Person:
    def __init__(self, first_name):
        self.first_name = first_name

    @property
    def first_name(self):
        return self._first_name

    @first_name.setter
    def first_name(self, value):
        if not isinstance(value, str):
            raise TypeError('Excepted str')
        self._first_name = value

    @first_name.deleter
    def first_name(self):
        raise AttributeError('Can not delete attribute.')

对类输入参数进行约束

可以通过定义描述器来对输入参数进行一定的约束。如对参数的类型进行约束,对输入数据的长度进行约束。

class Descriptor:
    def __init__(self, name=None, **opts):
        self.name = name
        for key, value in opts.items():
            setattr(self, key, value)

    def __set__(self, instance, value):
        instance.__dict__[self.name] = value


class Typed(Descriptor):
    excepted_type = type(None)

    def __set__(self, instance, value):
        if not isinstance(value, self.excepted_type):
            raise TypeError('Excepted ' + str(self.excepted_type))
        super().__set__(instance, value)

# 约束输入参数为int
class Integer(Typed):
    excepted_type = int

# 要求输入为字符串
class String(Typed):
    excepted_type = str
    
# 约束最大输入长度
class MaxSized(Descriptor):
    def __init__(self, name=None, **opts):
        if 'size' not in opts:
            raise TypeError('missing size option')
        super().__init__(name, **opts)

    def __set__(self, instance, value):
        if len(value) >= self.size:
            raise ValueError('size must be < ' + str(self.size))
        super().__set__(instance, value)
        
 # 要求参数大于等于0
 class Unsigned(Descriptor):
    def __set__(self, instance, value):
        if value < 0:
            raise TypeError('Excepted >= 0')
        super().__set__(instance, value)
  
# 要求输入为有长度限制的str
class SizedString(String, MaxSized):
    pass

# 要求输入为大于等于0的int
class UnsignedInt(Integer, Unsigned):
    pass

# 装饰器用于代替类似shares=UnsignedInteger('shares')的操作
def check_attributes(**kwargs):
    def decorate(cls):
        for key, value in kwargs.items():
            if isinstance(value, Descriptor):
                value.name = key
                setattr(cls, key, value)
            else:
                setattr(cls, key, value(key))
        return cls
    return decorate


@check_attributes(name=SizedString(size=8),
                  shares=UnsignedInteger,
                  price=UnsignedInteger)
class Stock:
    def __init__(self, name, shares, price):
        self.name = name
        self.shares = shares
        self.price = price
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值