内置函数/反射/内置方法(单例类面)

1.补充两个类这里相关的内置函数:

  issubclass(子类,父类)   用于判断前者是不是后者的子类

  isinstance(对象,类)      用于判断前者是不是后者这个类的对象

                                     这种判断是广义的,有深度,包含被继承的父类们的....

  对象 is type(类)            这种判断是狭义的,不继承,只限于后面给出来的类

2.反射:

反射是指:用字符串类型的变量名来访问这个变量

使用场景:用户的输入内容是字符串类型的,且是不安全的.如何获取字符串的内容并安全地调用是反射的具体应用

2.1 使用类名进行反射:

命名空间.XXX 等效于 getatter(命名空间,'XXX')
#命名空间.XXX 等效于 getatter(命名空间,'XXX')
class Student:
    ROLE = 'STUDENT'
    @classmethod
    def check_course(cla):
        print('查看所有课')

    @staticmethod
    def login():
        print('登录')

print(Student.ROLE)
#用户输入的内容是字符串,如果用eval()处理,容易崩,慎用,网络来源的数据和用户输入的是不能用的
print(getattr(Student,'ROLE'))           #后面的是变量名且确实是字符串
#第一个参数的命名空间的变量名为第二个参数的值

#反射调用方法
print(getattr(Student,'check_course'))   #打印的是对应的方法地址,方法名加括号即执行,见下
getattr(Student,'check_course')()
getattr(Student,'login')()

这是一种安全措施,先由
hasattr()函数确定所输入内容在这个类中再调用,不在则另行处理,hasattr()和getattr()通常配套使用
num = input('输入') print(hasattr(Student,num) ) #用于判断输入的内容在前面这个类中到底有没有,无则F,有则T 

if hasattr(Student,num):
   getattr(Student,num)()

2.2利用对象调用反射和类的调用基本相同

2.3利用模块调用反射自己模块当中的内容,需找到自己当前文件所在的命名空间

import 模块   

getattr(模块,'名字')=模块名.方法名=调用这个方法,再给它加括号和参数即可调用

2.4利用模块调用反射自己文件当中的内容,需找到自己当前文件所在的命名空间

import sys

getattr(sys.modules['__main__'],'名字')=自己文件.名字=调用这个方法,再给它加括号和参数即可调用

3.内置方法

__call__方法
对象名加括号,自动执行__call__
可以在构造函数内把别的类实例化为的一个对象作为self的属性(就是一种组合),然后调这个属性的__call__

__len__方法

类外执行len(对象)相当于调用这个对象对应类内的__len__方法,具体内容自己设置

__new__方法

用于开辟内存空间,一般自定义的类在实例化的时候都无法自己开辟空间,自动去找父亲object里的了,其返回值传给了self,在双init之前执行。

在执行双下new方法之前是没有产生self的,其方法默认函数只能写cls
单例类:
如果一个类从头到尾只能创建一个实例,那么就是个单例类。一般的类是可以随便无穷无尽进行实例化的。
单例则说明从头到尾只开辟了一个空间
   先在类里设置一个值为空的私有属性,在双下new执行前加一个该私有属性是否为空的判断,是则开辟,不是则返回之前开出来的内容(即这个私有属性)

背住!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

class Single:
    __stayrom = None
    def __new__(cls, *args, **kwargs):               #__new__的作用是开辟一块内存地址出来,然后将其传给对象的self
        if not cls.__stayrom:
            cls.__stayrom = object.__new__(cls)
        else:
            return cls.__stayrom

    def __init__(self, name):
        pass
s1 = Single()

无论是实例化几次都是对同一块内存地址的内容进行操作

输出的结果是最终实例化之后反复覆盖的结果

 

__str__方法

1.打印对象名,就可以直接调用双下str方法。
2.str(对象名)等于obj.双下str
3.格式化输出的对象名,也相当于格式化输出__str__方法 的返回值'%s'/%obj,相当于执行obj.__str__方法

 

posted @ 2019-07-07 21:52  眼见高楼起  阅读(138)  评论(0编辑  收藏  举报