• python_面向对象-反射与常用内置方法


    一、反射

      1、反射是什么?

        使用字符串数据类型的变量名来获取这个变量的值

      2、常用几个场景?

        input

          根据用户的输入,获取相应的值

        文件

          从文件读出的字符串,想转成变量的名字

        网络

          将网络传输的字符串转成变量的名字

      3、getattr 与 hasattr

         getattr(变量名:命名空间,字符串:属于一个命名空间中的变量)   

    # 反射类中的静态属性,类方法,静态方法
    class Foo:
        School = '希望小学'
        country = 'china'
    
        @classmethod
        def class_method(cls):
            print(cls.School)
    
        def static_method():
            print('is static')
    
    while 1:
        inp = input('<<<').strip()
        print(getattr(Foo,inp))
    View Code
    # 反射对象中的变量,普通方法,对象属性
    class Foo:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def eat(self):
            print('吃东西')
    
    f = Foo('xiaoming',12)
    print(getattr(f,'name'))
    print(getattr(f,'age'))
    getattr(f,'eat')()
    View Code
    # 反射本文件中的变量
    a = 1
    def fun():
        print('xxx')
    class Foo:pass
    import sys
    # print(sys.modules['__main__'])  #获取本文件的命名空间  F:/Demo/面向对象/反射与内置方法.py
    # print(sys.modules['__main__'].a)
    # print(__name__)
    
    print(getattr(sys.modules[__name__],'a'))
    print(getattr(sys.modules[__name__],'fun')())
    obj = getattr(sys.modules[__name__],'Foo')()
    print(obj)
    View Code

       4、setattr 与      delattr

    class Foo:
        country = 'china'
    
    def fun():
        print('xxx')
    
    setattr(Foo,'country','us')  #接收三个参数 命名空间 变量名 变量值
    print(Foo.__dict__)
    print(getattr(Foo,'country'))
    print(Foo.country)
    
    setattr(Foo,'fun',fun)
    print(Foo.__dict__)
    getattr(Foo,'fun')()  #一般不往空间中添加函数
    
    delattr(Foo,'country')
    print(Foo.__dict__)
    View Code

    二、内置方法

      1、不需要自己定义,本身就存在类中的方法

         一般都是__变量名__,又叫双下方法,魔术方法

      2、__str__  __repr__

    class Course:
        def __init__(self,name,price,teacher):
            self.name = name
            self.price = price
            self.teacher = teacher
    
        def __str__(self):
            return 'str: %s %s %s' %(self.name,self.price,self.teacher)
    
        def __repr__(self):
            return 'repr: %s %s %s' % (self.name, self.price, self.teacher)
    
    course_list = []
    python = Course('python',29800,'jing-l')
    linux = Course('linux',9800,'taix)
    
    course_list.append(python)
    course_list.append(linux)
    
    for id,course in enumerate(course_list,1):
        print(id,course)
        print('%s %s' %(id,course))
        print(id,str(course))
    
        print(id,repr(course))
        print('%s %r' %(id,course))
    # __str__
    # 当你打印一个对象的时候  触发__str__
    # 当你使用%s格式化的时候  触发__str__
    # str强转数据类型的时候   触发__str__
    
    # __repr__
    # repr是str的备胎
    # 有__str__的时候执行__str__,没有实现__str__的时候,执行__repr__
    # repr(obj)内置函数对应的结果是 __repr__的返回值
    # 当你使用%r格式化的时候 触发__repr__
    View Code

        3、__new__

    # 在init之前实例化对象的第一步是__new__创建了一个空间
    # 单例模式
    class Foo:
        __instance = None
        def __init__(self,name):
            self.name = name
    
        def __new__(cls, *args, **kwargs):
            if cls.__instance is None:
                cls.__instance = object.__new__(cls)
            return cls.__instance
    
    f1 = Foo('alex')
    f2 = Foo('zs')
    View Code

        4、__del__

    class Foo:
        def __init__(self,name):
            self.name = name
            self.file = open('file.txt','w')
    
        def write(self):
            self.file.write('aaa')
    
        def __del__(self):    # 析构方法 : 在删除这个类创建的对象的时候会先触发这个方法,再删除对象
             # 做一些清理工作,比如说关闭文件,关闭网络的链接,数据库的链接
            self.file.close()
            print('执行del了')
    
    f = Foo('zs')
    print(f)
    View Code

       5、__len__

    class Foo:
        def __init__(self,name):
            self.name = name
            self.students = []
    
        def __len__(self):
            return len(self.students)
    
    s1 = Foo('无极限')
    s1.students.append('zs')
    s1.students.append('lisi')
    s1.students.append('xm')
    print(len(s1))
    View Code

       6、__eq__

    class Staff:
        def __init__(self,name,sex):
            self.name = name
            self.sex = sex
    
        def __eq__(self, other):
            # 原本是比较id内存地址
            return self.__dict__ == other.__dict__
    
    s1 = Staff('asf','male')
    s2 = Staff('asf','male')
    s3 = Staff('asf','fmale')
    print(s1 == s2)
    print(s3 == s2)
    View Code

       7、__hash__  

      set 的去重机制
    1.对每一个元素进行hash计算出一个内存地址
    2.到这个内存地址上查看
    如果这块内存中没有值
    将这个元素存到对应的内存地址上
    如果这块内存中已经有值
    判断这两个值是否相等
    如果相等 就舍弃后面的值
    如果不相等 就二次寻址再找一个新的空间来存储这个值
    # 1.对于相同的值在一次程序的运行中是不会变化的
    # 2.对于不同的值在一次程序的运行中总是不同的
    class Staff:
        def __init__(self,name,age,sex,dep):
            self.name = name
            self.age = age
            self.sex = sex
            self.dep = dep
        def __hash__(self):
            return hash(self.name + self.sex)
        def __eq__(self, other):
            if self.name == other.name and self.sex == other.sex:
                return True
    
    name_lst = ['yuan','egon','nazha','peiqi']
    obj_lst = []
    for i in range(100):
        name = name_lst[i%4]
        obj = Staff(name,i,'male','python')
        obj_lst.append(obj)
    print(len(obj_lst))
    ret = set(obj_lst)
    print(ret)
    for i in ret:
        print(i.name,i.age)
    View Code
  • 相关阅读:
    内置函数
    打印进度条
    生成器表达式
    Linux(CentOS7)安装Tomcat (Tomcat+JDK)
    IDEA左侧文件目录不见了,帮你找回来!
    前端插入date类型的数据到数据库
    Java Web制作登录 验证码
    Java使用数据库连接池连接Oracle数据库
    Java Web项目实现写日志功能
    IDEA编写JavaWeb出现乱码,成功解决!
  • 原文地址:https://www.cnblogs.com/echo-up/p/9568169.html
Copyright © 2020-2023  润新知