类和对象plus

目录

一、鸭子类型和多态

二、抽象基类(abc模块)

三、isinstance和type的区别

四、类变量和实例变量

五、类和实例属性的查找顺序:__mro__

六、 静态方法、类方法以及对象方法

七、数据封装和私有属性

八、python的自省机制

九、super

十、with语句:上下文管理器

1、

2、简化上下文管理器


一、鸭子类型和多态

看到一只鸟走起来像鸭子,游泳起来像鸭子,叫起来也像鸭子,那么这只鸟就可以被称为鸭子。

class Cat(object):
    def say(self):
        print("i am a cat")


class Dog(object):
    def say(self):
        print("i am a fish")

class Duck(object):
    def say(self):
        print("i am a duck")


animal_list = [Cat, Dog, Duck]
for animal in animal_list:  # 每个类中有同样的方法,可以同时调用,就是鸭子类型的用法
    animal().say()

天然支持多态。

二、抽象基类(abc模块)

1、在抽象基类中实现某些方法,继承的类必须重载这些方法。

2、抽象基类无法实例化。

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):
        pass

redis_cache = RedisCache()

三、isinstance和type的区别

尽量使用isinstance

class A:
    pass

class B(A):
    pass

b = B()

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

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

四、类变量和实例变量

class A:
    aa = 1

    def __init__(self, x, y):
        self.x = x
        self.y = y


a = A(2, 3)

A.aa = 11   #类变量
a.aa = 100  #实例变量 
print(a.x, a.y, a.aa) # 2 3 100
print(A.aa)  # 11

五、类和实例属性的查找顺序:__mro__

#新式类
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'>)

六、 静态方法、类方法以及对象方法

classmethod。 : 定义操作类, 而不是操作实例的方法。 classmethod 改变了调用方法的方式, 因此类方法的第一个参数是类本身, 而不是实例。 classmethod 最常见的用途是定义备选构造方法
staticmethod: 装饰器也会改变方法的调用方式, 但是第一个参数不是特殊的值。 其实, 静态方法就是普通的函数, 只是碰巧在类的定义体中, 而不是在模块层定义。
 

class Demo(object):
    @classmethod
    def klassmeth(*args):
        return args

    @staticmethod
    def statmeth(*args):
        return args
print(Demo.klassmeth()) #返回全部位置参数
print(Demo.klassmeth('spam')) #不管怎样调用类方法装饰器装饰过的方法,第一个参数始终是类本身
print(Demo.statmeth()) #静态方法装饰器装饰后与普通函数类似
print(Demo.statmeth('spam'))

 classmethod装饰器非常有用,staticmethod装饰器并非必须使用,也可以在模块中定义函数。

七、数据封装和私有属性

from class_method import Date  #上一个的Date类
class User:
    def __init__(self, birthday):
        self.__birthday = birthday       #私有属性

    def get_age(self):
        #返回年龄
        return 2019 - self.__birthday.year


if __name__ == "__main__":
    user = User(Date(1998,2,9))
    print(user._User__birthday) #虽然是私有的属性,但是也可以通过  对象._类__属性  获得属性,并不是绝对安全的
    print(user.get_age())

八、python的自省机制

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

说的更简单直白一点:自省就是面向对象的语言所写的程序在运行时,能够知道对象的类型。简单一句就是,运行时能够获知对象的类型

Python中比较常见的自省(introspection)机制(函数用法)有: dir(),type(), hasattr(), isinstance(),__dict__,通过这些函数,我们能够在程序运行时得知对象的类型,判断对象是否存在某个属性,访问对象的属性。

九、super

super并不是调用父类的方法,而是按照__mro__方法的顺序调用的。

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__":
    print(D.__mro__)
    d = D()

>>>(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class    
  '__main__.A'>, <class 'object'>)
>>>D
>>>B
>>>C
>>>A

十、with语句:上下文管理器

1、

上下文管理器对象存在的目的是管理with语句,就像迭代器的存在是为了管理for语句一样。

with语句的目的是简化try/finally模式。这种模式用于保证一段代码运行完毕后执行某项操作,即便那段代码由于异常、return语句或sys.exit()调用而中止,也会执行指定的操作。finally语句中的代码通常用于释放重要的资源,或者还原临时变更的状态。

 

上下文管理器协议包含__enter__和__exit__两个方法。with语句开始运行时,会在上下文管理器对象上调用__enter__方法,with语句结束运行后,会在上下文管理器对象上调用__exit__方法,以此扮演finally子句的角色。

#上下文管理器协议
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 ("doing something")

with Sample() as sample:
    sample.do_something()

2、简化上下文管理器

contextlib中的contextmanager装饰器可以把简单的生成器函数变成上下文管理器,这样就不用创建类去实现管理器协议了。

import contextlib


@contextlib.contextmanager
def file_open(file_name):
    print("file open")
    yield {}  # 必须是一个生成器
    print("file end")


with file_open(".txt") as f_opened:
    print("file processing")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值