python day21 ——面向对像-反射 getattr,内置方法

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

上代码^_^

# class Student:
#     ROLE = 'STUDENT'
#     @classmethod
#     def check_course(cls):
#         print('查看课程了')
#
#     @staticmethod
#     def login():
#         print('登录')

# # 反射查看属性
# # print(Student.ROLE)#普通方法
# # print(getattr(Student,'ROLE'))
#
# # 反射调用方法
# # getattr(Student,'check_course')() # 使用类中的方法
# # getattr(Student,'login')() # 使用静态方法
 

用对象来反射

# class A():
#     def __init__(self,name):
#         self.name = name
#
#     def func(self):
#         print('in func')
#
# a = A('alex')#实例化一个对象
# print(a.name)
# print(getattr(a,'name'))#获得属性值
# getattr(a,'func')()#执行方法

是不是还挺好理解的啊!!

模块角度

好像是不是有xxx.xxx就能用到啊,模块四不四 from xxx import xxx.xxx啊,对就能用。

# import os   # 别人写好的python代码的结合
# # os.rename('__init__.py','init')#改文件名的功能
# # getattr(os,'rename')('init','__init__.py') #功能和上面一样后面是参数。
# rename = os.rename
# rename2 = getattr(os,'rename')
# rename2('__init__.py','init')  # os.rename('__init__.py','init')
# rename('init','init2')          # os.rename('init','init2')
下一个是 反射自己模块中的内容  找到自己当前文件所在的命名空间。这个有点不好理解,不过聪明人会先记住有机会慢慢在理解。
# import sys
# print(sys.modules)#查看当前模块,返回的是一个字典
# import 都相当于导入了一个模块
# 模块哪个导入了 哪个没导入 在我的python解释器里应该记录下来
# import sys 是一个模块,这个模块里的所有的方法都是和python解释器相关的
# sys.modules 这个方法 表示所有在当前这个python程序中导入的模块
# '__main__': <module '__main__' from 'D:/sylar/python_workspace/day20/4.反射.py'>
# print(sys.modules['__main__'])
# my_file = sys.modules['__main__']#这个先记住
# my_file.wahaha()
# my_file.qqxing()
# # 'qqxing'
# # 'wahaha'
# getattr(my_file,'wahaha')()
# getattr(my_file,'qqxing')()

总结下

# 反射
# hasattr,getattr
# 类名.名字
    # getattr(类名,'名字')
# 对象名.名字
    # getattr(对象,'名字')
# 模块名.名字
    # import 模块
    # getattr(模块,'名字')
# 自己文件.名字
    # import sys
    # getattr(sys.modules['__main__'],'名字')

下面来个实际应用场景,理解后背下来自己敲一便。

# class Manager:
#     OPERATE_DIC = [
#         ('创造学生账号', 'create_student'),
#         ('创建课程','create_course'),
#         ('查看学生信息','check_student_info'),
#     ]
#     def __init__(self,name):
#         self.name = name
#     def create_student(self):
#         print('创建学生账号')
#     def create_course(self):
#         print('创建课程')
#     def check_student_info(self):
#         print('查看学生信息')
#
# class Student:
#     OPERATE_DIC = [
#         ('查看所有课程', 'check_course'),
#         ('选择课程', 'choose_course'),
#         ('查看已选择的课程', 'choosed_course')
#     ]
#     def __init__(self,name):
#         self.name = name
#     def check_course(self):
#         print('check_course')
#     def choose_course(self):
#         print('choose_course')
#     def choosed_course(self):
#         print('查看已选择的课程')
#
# def login():
#     username = input('user : ')
#     password = input('pwd : ')
#     with open('userinfo') as f:
#         for line in f:
#             user,pwd,ident = line.strip().split('|')   # ident = 'Manager'
#             if user == username and pwd == password:
#                 print('登录成功')
#                 return username,ident
#
# import sys
# def main():
#     usr,id = login()
#     print('user,id :',usr,id)
#     file = sys.modules['__main__']
#     cls = getattr(file,id)     #Manager = getattr(当前文件,'Manager'),获得对应的类
#     obj = cls(usr)
#     operate_dic = cls.OPERATE_DIC
#     while True:
#         for num,i in enumerate(operate_dic,1):
#             print(num,i[0])
#         choice = int(input('num >>>'))
#         choice_item = operate_dic[choice-1]
#         getattr(obj,choice_item[1])()
#
#
#
# main()

主要是实现登陆和特定人员的选择和更改。

二、内置方法:有些函数里面带了特定的方法,比如len()里面可能有__len__这个方法

# __名字__
# 类中的特殊方法内置方法
# 双下方法
# 魔术方法 magic_method
# 类中的每一个双下方法都有它自己的特殊意义

1.__call__
# class A:
#     def __call__(self, *args, **kwargs):
#         print('执行call方法了')
#     def call(self):
#         print('执行call方法了')
# class B:
#     def __init__(self,cls):
#         print('在实例化A之前做一些事情')
#         self.a = cls()
#         self.a()
#         print('在实例化A之后做一些事情')
# a = A()
# a()  # 对象() == 相当于调用__call__方法
# a.call()#就调用类里面的__call__方法了
# A()() # 类名()() ,相当于先实例化得到一个对象,再对对象(),==>和上面的结果一样,相当于调用__call__方法
# B(A)
 

2.__len__  

# 内置函数和类的内置方法是由奸情的
# class My:
#     def __init__(self,s):
#         self.s = s
#     def __len__(self):
#         return len(self.s)
# my = My('abc')
# print(len(my))

 3.__new__

# class Single:
#     def __new__(cls, *args, **kwargs):
#         obj=object.__new__(cls)
#         print('在new方法里',obj)
#         return  obj
#     def __init__(self):
#         print('在init方法里',self)
#执行顺序
#1.开辟一个空间,属于对象的
#2.把对象的空间传给self,执行init
#3.将这个对象的空间返回给调用者
#new 方法在什么时候执行?
#在实例化对象之后,__init__之前先执行__new__来创建一块空间

单例类,背下来面试题
class Single:
    __isinstance=None
    def __new__(cls, *args, **kwargs):
        if not cls.__isinstance:
            cls.__isinstance=object.__new__(cls)
        return cls.__isinstance
    def __init__(self,name,age):
        self.name=name
        self.age=age
        print( self)

a=Single('aaa',56)
b=Single('sdf',55)
print(a.name)

只要前面实例化一个对象,就会开辟一个内存空间。后面的实例化对象不能开辟新的内存空间,后面的对象传进去的参数会覆盖前面对象的参数。



原文地址:https://www.cnblogs.com/snackpython/p/10067942.html