码迷,mamicode.com
首页 > 其他好文 > 详细

面向对象进阶

时间:2019-10-12 15:51:59      阅读:68      评论:0      收藏:0      [点我收藏+]

标签:pen   @class   没有   一个   单例   stat   set   self   __new__   

类方法和静态方法

类方法和实例方法

类方法
@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

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

  • getattr

    在类或实例中取‘字符串‘属性,有则返回对应值,无则报错

  • setattr

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

  • delattr

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

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__在调用类时触发

__str__在打印的时候触发

__del__在对象销毁先执行,不管del方法定义在前或后,总是最后执行

__getattr__在对象使用.调用属性,且此属性没有时触发

__setattr__会在对象使用.调用属性,且属性等于属性值时触发

__call__ 会在对象被调用时触发

__new__ 会在__init__执行前触发,new才是第一个执行的函数,用处较少

__getattribute__当发生.调用属性时,无论属性是否存在都会执行,当getattribute和getattr同时存在,只会执行getattribute,除非getattribute执行过程中抛错

__module__表示当前操作的对象在那个模块

__class__表示当前操作的对象的类时什么

面向对象进阶

标签:pen   @class   没有   一个   单例   stat   set   self   __new__   

原文地址:https://www.cnblogs.com/agsol/p/11661934.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!