• python学习Day21--内置函数、反射


    【知识点】

    1、isinstance()  判断对象所属类型,包含继承关系

      type()与isinstance()的区别

    1 class mystr(str):pass
    2 ms=mystr('alex')
    3 print(ms)
    4 print(type(ms) is str)    # 不包含继承关系,只管一层
    5 print(isinstance(ms,str)) # 包含所有的继承关系

    2、issubclass(B,A)    判断B是不是A的子类(判断类与类之间的继承关系)

    3、反射:用字符串数据类型的变量名来访问这个变量的值 

       方法:getattr   hasattr    setattr     delattr

     (1)在类的应用:静态属性(静态字段)、类方法、静态方法

       命名空间.XXX=getattr(命名空间,'XXX')   属性直接用,方法在后加()

     1 class Student:
     2     ROLE='STUDENT'
     3 
     4     @classmethod
     5     def check_course(cls):
     6         print("查看课程了")
     7 
     8     @staticmethod
     9     def login():
    10         print("登录")
    11 # 反射查看属性
    12 print(Student.ROLE)  # 通过类名调用
    13 print(getattr(Student,'ROLE'))
    14 
    15 # 反射调用方法
    16 getattr(Student,'check_course')()     # 查看课程了  # 类方法
    17 getattr(Student,'login')()            # 登录       # 静态方法
    18 
    19 num=input("请输入要调用的方法>>>")
    20 if hasattr(Student,num):         # 如果输入的num是Student这个命名空间里的方法,则返回True,否则返回Flase
    21     getattr(Student,num)()
    22 else:
    23     num = input("你输入的有误,请重新输入要调用的方法>>>")

      (2)在对象中应用:

     1 # 在对象中
     2 class A():
     3     def __init__(self,name):
     4         self.name=name
     5 
     6     def func(self):
     7         print("in func")
     8 
     9 a=A('123')
    10 print(a.name)            # 123
    11 print(getattr(a,'name')) # 123
    12 getattr(a,'func')()      # in func

      (3)在模块中

     1 # 在模块
     2 import os
     3 '''
     4 # os.rename('__init__.py','init')
     5 # getattr(os,'rename')('init','__init__.py')
     6 rename=os.rename
     7 rename2=getattr(os,'rename')  
     8 rename('__init__.py','init')   # os.rename('__init__.py','init')
     9 rename2('init','__init__.py')  # getattr(os,'rename')('init','__init__.py')
    10 '''
    11 # 反射自己模块中的内容,找到自己当前文件所在的命名空间
    12 def wahaha():
    13     print("wahaha")
    14 
    15 def qqxing():
    16     print("qqxing")
    17 
    18 # wahaha()
    19 # qqxing()
    20 
    21 import sys
    22 # print(sys.modules)
    23 # sys.modules 这个方法,表示所有在当前这个python程序中导入的模块
    24 # print(sys.modules['__main__'])
    25 my_file=sys.modules['__main__']  # 当前文件所在模块
    26 # my_file.wahaha()
    27 
    28 getattr(my_file,'wahaha')()   # wahaha

      【反射总结】

        hasattr    getattr

        ① 类名.名字 

          getattr(类名,'名字')

        ② 对象名.名字

          getattr(对象,'名字')

        ③ 模块名.名字

          import 模块

          getattr(模块,'名字')

        ④ 自己文件.名字

          import sys

          getattr(sys.modules['__main__'],'名字')

      【反射的应用】

     1 # 一个选课查询系统
     2 class Manager():
     3     OPERATE_DIC=[
     4         ('create_student','创建学生账号'),
     5         ('create_course','创建学生课程'),
     6         ('check_student','查看学生信息')
     7     ]
     8 
     9     def __init__(self,name):
    10         self.name=name
    11 
    12     def create_student(self):
    13         print("创建学生账号")
    14 
    15     def create_course(self):
    16         print("创建学生课程")
    17 
    18     def check_student(self):
    19         print("查看学生信息")
    20 
    21 
    22 class Student():
    23     OPERATE_DIC = [
    24         ('choose_course', '学生选择课程'),
    25         ('check_course', '学生查询课程')
    26     ]
    27 
    28     def __init__(self,name):
    29         self.name=name
    30 
    31     def choose_course(self):
    32         print("学生选择课程")
    33 
    34     def check_course(self):
    35         print("学生查询课程")
    36 
    37 
    38 def login():
    39     count=1
    40     while count<4:
    41         username=input("请输入用户名:")
    42         password=input("请输入密码:")
    43         with open('userinfo',mode='r',encoding='utf-8') as f:
    44             for line in f:
    45                 user,pwd,ident=line.strip().split('|')
    46                 if username == user and password == pwd:
    47                     print("登录成功")
    48                     return username,ident
    49                 else:
    50                     print("输入错误,请重新输入,你还有%d次机会" % (3-count))
    51                     break
    52             count+=1
    53 
    54 import sys
    55 def main():
    56     while True:
    57         user,id=login()
    58         file=sys.modules['__main__']  # 拿到自己当前所在的模块
    59         cls=getattr(file,id)          # id=manager,student 所以可以拿到相应的类
    60         obj=cls(user)                 # 类的实例化,并传入参数
    61         lst=getattr(cls,'OPERATE_DIC')    # 通过类拿到静态属性值
    62         for num,el in enumerate(lst,1):   # enumerate()是将列表中元素添加上序号,从1开始则需要添加起始参数1
    63             print(num,el[1])             # num是序号,el是元组  el[1]获取元组的第二个参数
    64         i=int(input('请输入要选择项序号:'))
    65         getattr(obj,lst[i-1][0]) ()    # lst[i-1][0]得到的是字符串,故用getattr()方法
    66 main()

    4、内置函数

       __名字__

        # 类中的特殊方法内置方法

        #双下方法

        #魔术方法

      类中的每一个双下方法都有它自己的特殊意义

    (1)__call__ 方法

      对象() 相当于调用__call__方法

      类名()() 相当于先实例化一个对象,再对对象()。与上面结果一样

     1 # __call__
     2 class A:
     3     def __call__(self,*args,**kwargs):
     4         print("执行call方法了")
     5 
     6 class B:
     7     def __init__(self,cls):
     8         print("在实例化A之前做一些事")
     9         self.a=cls()
    10         self.a()
    11         print("在实例化A之后做一些事")
    12 # a=A()
    13 # a()    # 相当于调用__call__方法
    14 #A()() # 和上面结果一样,相当于调用__call__
    15 B(A)

    (2)__len__方法

      len(obj) 相当于调用了这个obj的__len__方法

      __len__方法return的值就是len函数返回的值

      #如果一个obj对象没有__len__方法,那么len函数就会报错

     1 # __len__方法
     2 #内置函数与类的内置方法是有奸情的
     3 class Mylist:
     4     def __init__(self):
     5         self.lst=[1,2,3,4,5,6]
     6         self.name='123'
     7         self.age=45
     8 
     9     def __len__(self):
    10         print("执行__len__方法了")
    11         return len(self.__dict__)
    12 m=Mylist()
    13 print(len(m))   # 执行__len__方法了   3

    (3)__new__方法(构造方法)

      在执行__init__之前,开辟一个空间。

     1 # __new__构造方法
     2 class Single:
     3     def __new__(cls,*args,**kwargs):
     4         obj=object.__new__(cls)
     5         print("在new方法里",obj)
     6         return obj
     7 
     8     def __init__(self):
     9         print("在init方法里",self)
    10 #1、开辟一个空间,属于对象的
    11 #2、把这个对象的空间传给self,执行init
    12 #3、将这个对象的空间返回给调用者
    13 obj=Single()         #结果:在new方法里 <__main__.Single object at 0x0000019F309D1978>
    14                      #结果:在init方法里 <__main__.Single object at 0x0000019F309D1978>
    15 #若是类中没有__nem__方法,则会调用object里的__new__来开辟空间

    【一道面试题】

      写出一个单例类?

      #1、单例:如果一个类,从头到尾只能有一个实例(说明从头到尾只开辟了一块属于对象的空间),那么这个类就是一个单例类。

      单例的例子代码:

     1 # 写一个单例类
     2 class Single:
     3     __ISINSTANCE=None
     4     def __new__(cls,*args,**kwargs):
     5         if not cls.__ISINSTANCE:
     6             cls.__ISINSTANCE=object.__new__(cls)
     7         return cls.__ISINSTANCE
     8 
     9     def __init__(self,name,age):
    10         self.name=name
    11         self.age=age
    12 
    13 s1=Single('太白',23)
    14 s2=Single('Alex',26)
    15 print(s1.name)        # Alex
    16 print(s2.name)        # Alex
    17 # 原因:首先开辟一个空间,并且只有一个空间。最开始将name赋值“太白”,age赋值23,
    18 # 然后执行S2=Single('Alex',26),由于只有一个空间,故将此前的值覆盖掉,所以最后打印都是“Alex”

    注意:上述例子首先开辟了一个空间,并且只有一个空间。最开始将name赋值“太白”,age赋值23,然后执行S2=Single('Alex',26),由于只有一个空间,故将此前的值覆盖掉,所以最后打印都是“Alex”。

    (4)__str__方法

      print(对象)  相当于调用一个对象的__str__方法

      str(obj)   相当于执行了obj.__str__方法

      '%s' % obj  相当于执行obj.__str__方法

     1 # __str__方法
     2 class Student:
     3     def __str__(self):
     4         return '%s %s %s' % (self.school,self.stu_cls,self.name)
     5 
     6     def __init__(self,name,stu_cls):
     7         self.school='oldboy'
     8         self.name=name
     9         self.stu_cls=stu_cls
    10 
    11 he=Student('菏泽微','py14')
    12 # print(he)    # 执行了__str__方法   结果:oldboy py14 菏泽微
    13 # print(str(he))  # 也执行了__str__方法,结果同上
    14 print('学生1:%s' % he)  # 也执行了__str__方法,结果同上

    【小结】所有的双下方法,没有需要你在外面调用的,而是总有一些其他的 内置函数 特殊的语法 来自动触发这些双下方法

  • 相关阅读:
    MarkDown 基本语法
    JavaScript 关于setTimeout与setInterval的小研究
    Openlayers 实现轨迹播放/暂停/重新播放/从点击处播放/提速/减速
    Openlayers ol.interaction.Select传值问题
    Openlayers ol.interaction.Select取消默认选中效果
    Openlayers Projection导致经纬度颠倒问题
    ArcGIS 切片与矢量图图层顺序问题
    PostGIS 爆管分析之找出总阀门
    计算机网络原理-5
    k8s中部署基于nfs的StorageClass
  • 原文地址:https://www.cnblogs.com/fengxb1213/p/12307568.html
Copyright © 2020-2023  润新知