面向对象进阶

类方法和静态方法

类方法和实例(静态)方法

类方法
@classmethod
def clsmtd(cls):
    print(xxx)

a = MyClass()

a.clsmtd()是可以调用的, 等同于a.__class__.clsmtd()

  1. 在类定义中,使用@classmethod装饰器修饰的方法
  2. 必须至少有一个参数,且第一个参数就给了cls,cls指调用者就是对象自己
  3. cls可以是任意合法名称,但是为了易读性,不要改
  4. 通过cls可以直接操作类的属性,但是无法通过cls操作类的实例
静态方法(非绑定方法)
@staticmethod
def staticmtd():
    print('static')
  1. 在类的定义中,使用@staticmethod装饰器修饰的方法
  2. 调用时,不会隐式传入参数

静态方法,指时表明这个方法属于这个名词空间,函数归结在一起,方便组织管理.

类和对象都可以调用,可以不传参

总结

类除了普通方法都可以调用,普通 方法 需要对象的实例作为第一参数.

实例可以调用所有类中定义的方法(包括类方法,静态方法),普通方法传入实例自身,静态方法和类方法需要找到实例的类.

被@classmethod装饰器装饰的方法是类的绑定方法,参数协程cls,cls是类本身,对象也能调用,参数cls还是还是类本身

被@staticmethod装饰器装饰的方法就是非绑定方法,就是一个普通函数

isinstance和issubclass

isinstance(o,c)

判断o是否为c的实例对象,c可为o的类,或父类及爷爷类

print(isinstance(True,int))
>>>True

issubclass(o,c)

判断o是否为c的子类

print(issubclass(bool,int))
>>>True

反射

反射本质时通过字符串来判断或操作类或者实例的属性

  • hasattr(obj,str)

    判断字符串是否是否为类或实例的属性

  • getattr(obj,str,default)

    在类或实例中取'字符串'属性,有则返回对应值,无则返回缺省值,若没设定缺省值,抛错

  • setattr(obj,str,value)

    设置类或实例中的'字符串'属性,有则更改,无则添加

  • delattr(obj,name)

    删除类或实例中的'字符串''属性,有则删除,无则报错

class People:
    school = 'DHU'
    def __init__(self,name,age):
        self.name = name
        self.age = age


ag = People('agsol',18)
print(hasattr(ag,'name'))
setattr(People,'major','computer')
print(hasattr(People,'major'))
print(getattr(People,'school'))
delattr(People,'school')
print(hasattr(People,'school'))

>>>True
>>>True
>>>DHU
>>>False
>>>True

单例模式

为了节省内存空间,防止每次(每次实例化的目的以产生相同功能的对象)对类进行实例化都会产生一个新的内存空间

相当于在类的内部加一个中间变量接收这个实例化对象,每次都直接使用实例化对象来调用方法.

class File:

    __instance = None

    # 单例方式1:使用类方法在类内部生成一个对象
    @classmethod
    def singleton(cls, file_name):
        if not cls.__instance:
            obj = cls(file_name)
            cls.__instance = obj
        return cls.__instance

    # 单例方式2:通过调用__new__的方法
    def __new__(cls, *args, **kwargs):
        # cls.__new__(cls, *args, **kwargs)
        if not cls.__instance:
            cls.__instance = object.__new__(cls)
        return cls.__instance

    def __init__(self, file_name, mode='r', encoding='utf-8'):
        self.file_name = file_name
        self.mode = mode
        self.encoding = encoding

    def open(self):
        self.f = open(self.file_name, self.mode, encoding=self.encoding)

    def read(self):
        res = self.f.read()
        print(res)

    def close(self):
        self.f.close()

魔术方法

方法名 作用
__init__ 在调用类时触发.__new__没有返回一个空对象时不触发
__str__ 在打印的时候触发,如果没有定义,取调用repr方法,
__repr__ 对一个对象获取字符串表达,如果repr没有定义,直接返回object的定义就是显示内存地址信息
__del__ 在对象销毁先执行,不管del方法定义在前或后,总是最后执行
__getattr__ 在对象使用.调用属性,且此属性没有时触发
__setattr__ 会在对象使用.调用属性,且属性等于属性值时触发
__call__ 会在对象被调用时触发
__new__ 会在__init__执行前触发,new才是第一个执行的函数,用处较少,必须返回一个空对象
__getattribute__ 当发生.调用属性时,无论属性是否存在都会执行,当getattribute和getattr同时存在,只会执行getattribute,除非getattribute执行过程中抛错
__module__ 表示当前操作的对象在那个模块
__class__ 表示当前操作的对象的类时什么
__delattr__ 当删除属性时触发

查看属性

__dir__:返回类或者对象的所有成员名称列表.dir()函数就是调用__dir__().如果提供__dir__(),则返回属性的列表,否则会尽量从__dict__属性中搜集信息.

dir()对于不同类型的对象具有不同的行为:

如果对象是模块对象,返回的列表包含模块的属性名.

乳如果对象是类型(type)或者类对象(class),返回的列表包含类的属性名,及它的基类的属性名

否则,返回列表包含对象的属性名,它的类的属性名和类的基类的属性名.

posted @ 2019-10-12 15:42  Agsol  阅读(86)  评论(0编辑  收藏  举报