PythonCookBook 笔记 chapter-08-类01

1,类重写 __repr__() 和__str()__可以更方便调试

__repr__() 返回的是实例的代码表示,对程序员友好, 

__str__() 将实例转换为一个字符串

>>> class MyObj:
    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return 'Pair({!r})'.format(self.name)

    def __str__(self):
        return '({0.name!s})'.format(self) # 0.name 0表示self

>>> MyObj('Leon')
Pair('Leon')
>>> print(MyObj('Lily'))
(Lily)
>>> 

2, 上下文管理协议,with用法

具体with的概念参考:点击打开链接

class MyContextMgr:
    def __init__(self, name = 'AnyPlayer'):
        self.name = name

    def __enter__(self): # 当遇到with语句是,__enter__ 首先会被触发
        print('__enter__ self name: ', self.name)
        return self # 返回自身的引用,作为as限定的变量

    def __exit__(self,exc_ty, exc_val,tb): # 离开with语句块时被触发
        print('__exit__ self name: ', self.name)
        self.name = 'AnyPlayer'

    def set_name(self, name):
        self.name = name


test = MyContextMgr(('Hello'))
with test as t:
    t.set_name('leon')


out:
    __enter__ self name:  Hello
    __exit__ self name:  leon

3,利用@property装饰器将类的方法编程属性调用

class MyProperty:
    def __init__(self):
        self.name = ''

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        if not isinstance(value, str): # 类型检测
            raise TypeError('Expected a string')
        self._name = value

    @name.deleter
    def name(self):
        raise TypeError('Can not delete name')
    

a = MyProperty()
print(a.name)
a.name = 'Leon'
print(a.name)

out:
    
    Leon
class MyProperty:
    def __init__(self, name):
        self.set_name(name)

    def get_name(self):
        return self._name

    def set_name(self, value):
        if not isinstance(value, str):
            raise TypeError('Expected a string')
        self._name = value

    name = property(get_name,set_name)
    

a = MyProperty('Weight')
print(a.get_name)
print(a.get_name())


out:
    <bound method MyProperty.get_name of <__main__.MyProperty object at 0x0000000002B5B4A8>>
    Weight

4,利用super()可以很好的实现子类调用父类

python的继承:针对么一个定义的类,都会计算出一个称谓方法解析顺序(MRO)的列表,

该表只是简单地对所有的基类进行线性排列,要实现继承,python从MRO表中从最左边的类开始,

从左到右一次查找,知道找到待查的属性时为止。当时用super函数时,python会继续从MRO的

下一个类开始搜索,只要每一个重新定义过的方法都使用了super(), 并且只调用它一次,那么控制流

最终就可以遍历整个MRO列表,并且让每个方法只会被调用一次

class Animal:
    def __init__(self):
        print('--Animal--')

class Bird(Animal):
    def __init__(self):
        print('--Bird--')
        super().__init__()

b = Bird()

out:
    --Bird--
    --Animal--

简化初始化过程(利用setattr()函数来设定属性值)

class BaseInit:
    _fields = []
    def __init__(self, *args):
        if len(args) != len(self._fields):
            raise TypeError('Expected {} arguments'.format(len(self._fields)))

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

class Point(BaseInit):
    _fields = ['x', 'y']

class Circle(BaseInit):
    _fields = ['radius']
    def area(self):
        return 3.14 * self.radius ** 2

p = Point(2, 3)
c = Circle(4.5)
print(c.area())

5,利用abc定义接口类

from abc import ABCMeta, abstractmethod

class IAnimal(metaclass=ABCMeta):
    @abstractmethod
    def Fly(self):
        pass

class Bird(IAnimal):
    def Fly(self):
        print('Bird Fly')

b = Bird()
b.Fly()

def check_type(animal):
    if not isinstance(animal, IAnimal):
        print('Expected Obj')
    else:
        print('---ok----')

check_type(b)
check_type(IAnimal)

out:
    Bird Fly
    ---ok----
    Expected Obj


猜你喜欢

转载自blog.csdn.net/vitas_fly/article/details/80284407
今日推荐