反射及内置方法
知识点补充,内置函数enumerate
l = ["小明","小李","小白"]
for num,i in enumerate(l,1):#后面数字的1表示索引加1
print(num,i)
# 1 小明
# 2 小李
# 3 小白
isinstance() 判断对象所属类型,包括继承关系
issubclass() 判断类与类之间的继承关系
class A:
pass
class B(A):
pass
b = B()
print(isinstance(b,B)) #True
print(isinstance(b,A)) #True
class A:pass
class B(A):pass
print(issubclass(B,A))#True
print(issubclass(A,B))#False
什么是反射?
用字符串数据类型的变量名来访问这个变量的值
反射的方法: getattr hasattr (setattr delattr)不常用
setattr,delattr
class A:
def __init__(self,name):
self.name = name
a = A('alex')
setattr(a,'name','alex_SB')
print(a.name)#alex_SB
del a.name
print(a.__dict__)
delattr(a,"name")#{}
print(a.__dict__)
反射
hasattr,getattr
类名.名字
getattr(类名,'名字')
对象名.名字
getattr(对象,'名字')
模块名.名字
import 模块
getattr(模块,'名字')
自己文件.名字
import sys
getattr(sys.modules['__main__'],'名字')
类名或者对象使用getattr方法
class Person:
age = "18"
def __init__(self,name):
self.name = name
@classmethod
def work(cls):
return cls.age
@staticmethod
def pp():
return "oo"
p = Person("1")
print(getattr(p,"work")()) #getattr(方法名或者类名,字符串类型的属性名或者方法名)执行方法后面加()
print(getattr(p,"pp")())
print(getattr(p,"age"))
num = input("请输入")
if hasattr(p,num):#如果类或对象里面有这个属性或方法
getattr(p,num)()#则查看这个属性或者执行这个方法
else: print("shabi")#否则返回你要让他返回的内容
用系统模块和自己创建的模块使用getattr方法
import os
# os.rename("课程","白痴")
getattr(os,"rename")("白痴","课程")#getattr(模块名,字符串类型方法名)
import sys
def oo():
print("哦哦")
getattr(sys.modules["__main__"],"oo")()
反射的应用,选课系统
# 选课系统的代码
# login
# 判断身份 并且根据身份实例化
# 根据每个身份对应的类 让用户选择能够做的事情
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,id = line.strip().split('|') # ident = 'Manager'
if user == username and pwd == password:
print('登录成功')
return username,id
import sys
def main():
usr,id = login()
print('user,id :',usr,id)
cls = getattr(sys.modules['__main__'],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])()
内置方法
__call__ 相当于 对象()
class Student:
def __call__(self, *args, **kwargs):
print("oo")
s = Student()
s()#直接执行__call__方法
__len__ len(obj)
class Student:
def __init__(self,name):
self.name = name
def __len__(self):
return len(self.name)
s = Student("我是大帅哥")
print(len(s))#直接执行__len__方法,输出5
__new__ 特别重要 开辟内存空间的 类的构造方法,写一个单例类
class Person:
def __new__(cls, *args, **kwargs):
s = object.__new__(cls)
return s#返回那个空间
def __init__(self,name):
self.name = name
p = Person()#再实例化对象的时候执行__new__方法,开辟空间
单例类
class Person:
__age = None
def __new__(cls, *args, **kwargs):
if not cls.__age:#如果有空间,就不重新开辟空间
cls.__age = object.__new__(cls)
return cls.__age
def __init__(self,name):
self.name = name
p = Person("小明")
p2 = Person("小李")
print(p.name)
print(p2.name)#实例化的对象都在第一次开辟的空间里,后面实例化的对象属性也覆盖前面的对象属性,都输出小李
__str__ str(obj),'%s'%obj,print(obj)
class A:
def __str__(self):
return ("%s,%s,%s" % (self.name,self.age,self.sex))
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
a = A("小明","18","男")
print(str(a))
print(a)
print("%s"%a)#三个输出结果一样,都自动执行__str__方法
浙公网安备 33010602011771号