阅读 42

python 高级编程与异步IO并发编程(三)深入类和对象

1 鸭子类型和多态

维基百科:当看到一只鸟走起来像鸭子,游泳起来像鸭子,叫起来也像鸭子,那么这只鸟就可以被称为鸭子

class Cat(object):
    def say(self):
        print('i am a cat')
class Dog(object):
    def say(self):
        print('i am a dog')
class Duck(object):
    def say(self):
        print('i am a duck')

#animal=Cat
#animal().say()

#只需要共同实现say()方法就可以了
animal_list=[Cat,Dog.Duck]
    for animal in animal_list:
        animal().say()
a = ["today1","today2"]
b = ["today2","today"]
name_tuple = ["bobay3","bobay4"]
name_set = set()
name_set.add("today5")
name_set.add("today6")
a.extend(b)
print(a)

复制代码

2 抽象基类(abc模块) - 1

抽象基类(abstract base class)类似java中的接口

3 抽象基类(abc模块) - 2

class Company(object):
    def __init__(self,employee_list):
        self.employee=employee_list
        
    def __len__(self):
        return len(self.employee)
    
com=Company("today1","today2")
print(hasattr(com,"__len__"))
print(len(com))
复制代码

#我们希望在某些情况之下判定某个对象的类型

from collections.abc import Sized
is instance(com,Sized)
复制代码

#我们需要强制某个子类需要实现某些方法

#实现了一个web框架,集成cache(redis,cache,memerychache)

#需要设计一个抽象基类,指定子类必须实现某些方法

#如何去模拟一个抽象基类

import abc
class CacheBase(metac)
class CacheBase():
    def get(self,key)
        raise NotImplementedError
    def set(self,key,value):
        raise NotImplementedError
        
class RedisCache(CacheBase):
    pass
    
from collections.abc import *
class CacheBase(metaclass=abc.ABCMeta):
    @abc.abstractmethord
    def get(self,key):
        pass
    @abc.abstractmethord
    def set(self,key,value):
        rasie
class RedisCache(CacheBase): 
        pass
redis_cache=RedisCache()
复制代码

4 isinstance和type的区别

class A:
    pass
class B(A):
    pass

print(isinstance(b,B))
print(isinstance(b,A))

print(type(b) is A )
print(type(b) is B)
#尽量使用isinstance去判断类型,type主要是判断两个的值是否相等 
复制代码

5 类变量和实例变量

class A:
    aa=1
    #self是类的实例
    def __init__(self,x,y):
        self.x=x
        self.y=y
a=A(2,3)
print(a.x,a.y,a.aa)
A.aa=11
a.aa=100
print(a.x,a.y,a.aa)
print(a.aa)

b=A(3,5)
print(b.aa)
#先查找实例变量,然后查找类变量
复制代码

####6 类和实例属性的查找顺序—mro查找

class A:
    name="A"
    def __init__(self):
        self.name="obj"

a=A()
print(a.name)
#新式类
class D:
    pass
class C(D):
    pass
class B(D):
    pass
class A(B,C):
    pass
print(A.__mro__)
复制代码

7 类方法、静态方法和实例方法

class Date:
    #构造函数
    def __init__(self,,year,month,day):
        self.year=year
        seif.month=month
        self.day=day
        
    def __str__(self):
        return "{year}/{month}/{day}".format(year=self.year,month=self.month,day=self.day)
if __name++=="__main__":
    new_day=Date(2019,9,02)
    print(new_day)
#2019-09-02
data_str ="2019-9-02"
year,month,day=tuple(data_str,split("-"))
new_day=Date(int(year),int(month),int(day))
print(new_day)
####
复制代码

8 数据封装和私有属性

class User:
    def __init__(self,birthday):
        self.birthday =  birthday 

    def get_age(self):
        #返回年龄
        return 2018-self.birthday.year

if __name__=="__main__":
    User=User(Date(1990,2,1))
    print(User.get_age())
    print(User.birthday)
    print(User.get_age( ) )
复制代码

9 python对象的自省机制

#自省是通过一定的机制查询到对象的内部结构
class Person:
    name="user"

     
class Student(Person):
    def __init__(self,school_name):
        self.school_name=school_name

if __name__=="__main__":
    user=Student("慕课网")

    #通过__dict__查询属性
    print(user.__dict__)
    user.__dict__["school_addr"] ="北京市"
    print(user.school_addr)
    print(Person.__dict__)
    print(user.name)

    a=[1,2]
    print(dir(a))
复制代码

10 super真的是调用父类吗?

class A:
    def __init__(self):
        print("A")
class B(A):
    def __init__(self):
        print("B")
        super().__init__()

from threading import Thread
class MyThread(Thread):
    def __init__(self,name,user):
        self.user = user
        self.name = name
#既然重写了B的构造函数,为什么还要去调用super
#super到底执行顺序是什么样的?

if __name__=="__main__":
        b=B()

class A:
    def __init__(self):
            print("A")
class B(A):
    def __init__(self):
            print("B")
            super().__init__()
class C(A):
    def __init__(self):
        print ("C")
        super().__init__()
class D(B,C):
    def __init__(self):
        print ("D")
        super(D,self).__init__()

if __name__=="__main__":
    print(D.__mro__):
    d=D()
复制代码

11 mixin继承案例-django rest framework

#mixin模式特点

1.Mixin类功能单一

2.不和基类关联,可以和任意基类组合,基类可以不和Mixin关联就能初始化成功

3.在Mixin中不要使用super这种用法

class GoodsListViewSet(CacheResponseMixin,Mixins.ListModelMixin,mixins.RetrieveModelMixin
复制代码

12 python中的with语句

 #try,except,finally
try:
    print ("code started")
    raise KeyError
except KeyError as e:
    print ("Key error")
except IndexError as e:
else:
    print("other error")
finally:
    f_read.close()
复制代码
#try,except,finally
def exe_try():
        try:
            print ("code started")
            raise KeyError
            return 1
        except KeyError as e:
            print ("key error")
            return 2
        else:
            print("other error")
            return 3
        finally:
            print("finally")
            return 4
        if __name__=="__main__":
            result=exe_try
            print(result)
复制代码
#上下文管理器协议
class Sample():
    def __enter__(self):
        #获取资源
        print("enter")
        return self 
    def __exit__(self,exc_type,exc_val,exc_tb):
        #(释放资源)
        print("exit")
    def do_something(self):
        print ("do something")
        
with Sample() as sample:
    sample.do_something()
复制代码

13 contextlib简化上下文管理器

import contextlib
@contextlib.contextmanager
def file_open(file_name):
    print("file open")
    yield {}
    print ("file end")
    
with file_open("today.txt") as f_opened:
    print ("file processing")

复制代码

14 本章小结

python中一切皆对象,鸭子类型和多态,鸭子类型实际上没有接口,遵循了python中的一些协议将魔法函数进行组合,抽象基类,mixin,类变量和对象变量,对象自省,super查找顺序,with语句,contextlib上下文管理器.

关注下面的标签,发现更多相似文章
评论