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