深入理解类和对象

字数 253阅读 44

1.1 抽象基类(abc模块)

python的抽象类的写法,继承抽象类的类必须要实现抽象方法,否则会报错

import abc

class CacheBase(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def get(self, key):
        pass

    @abc.abstractmethod
    def set(self, key, value):
        pass

class RedisCache(CacheBase):
    def set(self, key, value):
        print("setMethod")
    def get(self, key):
        print("getMethod")

redis_cache = RedisCache()
redis_cache.get('kv')

class A:
    pass

class B(A):
    pass

b = B()

print(isinstance(b, B))   # True
print(isinstance(b, A))   # True
print(type(A) is B)         # False

1.2 类方法,静态方法,实例方法

类方法相对静态方法有一个好处, 类方法可以传入一个类的实例代表这个类,而不用把类名写死

class Date():
    # 构造函数
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

    #实例方法
        def tomorrow(self):
            self.day += 1

    @staticmethod
    def parse_from_string(date_str):
        year, month, day = tuple(date_str.split("-"))
        return Date(int(year), int(month), int(day))

    @classmethod
    def from_string(cls, date_str):
        year, month, day = tuple(date_str.split("-"))
        return cls(int(year), int(month), int(day))

    def __str__(self):
        return "{year}/{month}/{day}".format(year=self.year, month=self.month, day=self.day)

if __name__ == "__main__":

    date_str="2018-01-19"
    d = Date.from_string(date_str)
    print(d)                                              # 2018/1/19

1.3 类和实例方法查找顺序

Python在多继承时候查找顺序采用c3算法

菱形结构
class D:
    pass

class C(D):
    pass

class B(D):
    pass

class A(B,C):
    pass

#顺序:A,B,C,D
#__mro__,类的属性查找顺序
print(A.__mro__)              # (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>,<class '__main__.D'>, <class 'object'>)
广型结构
class D:
    pass

class E:
    pass

class C(E):
    pass

class B(D):
    pass

class A(B,C):
    pass

print(A.__mro__)      # (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.C'>, <class '__main__.E'>, <class 'object'>)

1.4 Python对象的自省机制

在计算机编程中,自省是指一种能力:检查某些事物以确定它是什么、它知道什么以及它能做什么。自省向程序员提供了极大的灵活性和控制力

class Person:
    """这是个人"""
    name = "lala"

class Student(Person):
    def __init__(self, scool_name):
        self.scool_name = scool_name
        self.lal = "纬度"

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

    # 通过__dict__查询属性
    user.__dict__["school_aadd"] = "沈阳"

    print(user.__dict__)                     # {'scool_name': '慕课网', 'lal': '纬度', 'school_aadd': '沈阳'}

    print(Person.__dict__)                   

    # {'__module__': '__main__', '__doc__': '这是个人', 'name': 'lala', '__dict__': <attribute '__dict__' of 'Person' objects>, 
    '__weakref__': <attribute '__weakref__' of 'Person' objects>}

    print(Person.__doc__)     # 这是个人

    # dir也可以查看属性,比__dict__功能更强大
    print(dir(user))

    # ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__',  '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__',  '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'lal', 'name', 'school_aadd', 'scool_name']

1.5 super函数执行顺序

一问super是干什么的, 都知道它调用父类的方法, 可它的调用顺序呢

# super执行顺序是怎样的
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().__init__()

if __name__ == "__main__":
    d = D()

1.6 with方法(上下文管理器)

with有点像装饰器,使用起来很方便

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("lala")

with Sample() as sample:
    sample.do_something()
# enter lala exit

推荐阅读更多精彩内容