特殊方法补充以及反射

一.特殊方法补充
1.__str__  使打印对象名时得到的不再是一个内存地址<__main__.Foo object at 0x000001B815568E10>
而是return 后面的字符串
1 class Foo:
2 
3     def __init__(self,name,age):
4         self.name=name
5         self.age=age
6     def __str__(self):
7         return '这个函数的名字或介绍等等'  #此处也可以返回一个obj2,需要鉴别
8 obj1=Foo('lisa',18)
9 print(obj1,type(obj1))  #这个函数的名字或介绍等等  <class '__main__.Foo'>
2.__doc__ 打印类的注释(不用在类中添加___doc__函数就可以)
 1 class Foo:
 2     '''
 3     这个类是做什么的
 4     '''
 5     def __init__(self,name,age):
 6         self.name=name
 7         self.age=age
 8 
 9     def __str__(self):
10         return '这个函数的名字或介绍等等'  #此处也可以返回一个obj2,需要鉴别
11 
12 obj1=Foo('lisa',18)
13 print(obj1.__doc__)  #这个类是做什么的
3.__dict__  直接打印对象.__dict__  将对象中封装的所有的值以字典的方式呈现
 1 class Foo:
 2 
 3     def __init__(self,name,age):
 4         self.name=name
 5         self.age=age
 6 
 7     def __str__(self):
 8         return '这个函数的名字或介绍等等'
 9 obj1=Foo('lisa',11)
10 obj2=Foo('sushan',12)
11 
12 print(obj1.__dict__)   #{'name': 'lisa', 'age': 11}
13 print(obj2.__dict__)    #{'name': 'sushan', 'age': 12}
4.__iter__  把不可迭代对象转换成可迭代对象,有以下两种方法
 1 l1=[11,22,33,44]
 2 l2=[1,2,3,4]
 3 
 4 class Foo:
 5 
 6     def __init__(self,name,age):
 7         self.name=name
 8         self.age=age
 9 
10     def func(self):
11         pass
12 
13     # def __iter__(self):
14     #     return iter([1,22,33,44,55,6])  #返回的是一个迭代器
15 
16     def __iter__(self):
17         yield 1
18         yield 2
19         yield 3
20         yield 4
21 
22 obj=Foo('as',1)
23 for item in obj:
24     print(item)
二.类变量与实例变量的区别:
 1 class Foo:
 2     country='中国哦'
 3     def __init__(self,name,age):
 4         self.name=name
 5         self.age=age
 6     def func(self):
 7         Foo.country='美国'
 8         print(Foo.country)
 9     def func1(self):
10         print(Foo.country)
11 obj=Foo('kl','jhh')
12 obj.func()
13 obj.func1()  #此时的func1里打印的也是美国,
14              说明类变量中的country是公共的在func中的修改也会延续到func1中
2.1.1
 1 class Foo:
 2     country='中国哦'
 3     def __init__(self,name,age):
 4         self.name=name
 5         self.age=age
 6     def func(self):
 7         self.name='胡歌'
 8         print(self.name)
 9     def func1(self):
10         print(self.name)
11 obj=Foo('彭于晏',34)
12 obj.func()
13 obj.func1()   #此时的func1里打印的也是胡歌
14              # 说明实例变量中的self.name是在一个对象中公共的在func中的修改也会延续到func1中
2.1.2
 1 class Foo:
 2     country='中国哦'
 3     def __init__(self,name,age):
 4         self.name=name
 5         self.age=age
 6     def func1(self):
 7         print(Foo.country)
 8     def func(self):
 9         Foo.country = '美国'
10         print(Foo.country)
11 
12 
13 obj1=Foo('Lisa',18)
14 obj2=Foo('linda',20)
15 
16 obj1.func1()
17 obj1.func()
18 
19 obj2.func1()
20 obj2.func()
类变量在各个对象中是公有的
 1 class Foo:
 2     country='中国哦'
 3     def __init__(self,name,age):
 4         self.name=name
 5         self.age=age
 6 
 7     def func1(self):
 8         print(self.name)
 9 
10     def func(self):
11         self.name='sushan'
12         print(self.name)
13 
14 
15 obj1=Foo('Lisa',18)
16 obj2=Foo('linda',20)
17 
18 obj1.func1()
19 obj1.func()
20 
21 obj2.func1()
22 obj2.func()
每一个对象都一份构造方法封装的实例变量

2.2 练习题

 1 class StarkConfig:
 2     list_display=[]
 3 
 4     def get_list_display(self):
 5         self.list_display.insert(0,33)
 6         return self.list_display
 7 
 8 class RoleConfig:
 9     list_display=[11,22]
10 
11 s1=StarkConfig()
12 ret1=s1.get_list_display()
13 print(ret1)
14 
15 ret2=s1.get_list_display()
16 print(ret2)
习题1
 1 class StarkConfig:
 2     def __init__(self):
 3         self.list_display=[]
 4 
 5     def get_list_display(self):
 6         self.list_display.insert(0,33)
 7         return self.list_display
 8 
 9 class RoleConfig:
10     list_display=[11,22]
11 
12 s1=StarkConfig()
13 ret1=s1.get_list_display()
14 print(ret1)
15 
16 ret2=s1.get_list_display()
17 print(ret2)
习题2
 1 class StarkConfig:
 2     def __init__(self):
 3         self.list_display=[]
 4 
 5     def get_list_display(self):
 6         self.list_display.insert(0,33)
 7         return self.list_display
 8 
 9 class RoleConfig(StarkConfig):
10     list_display=[11,22]
11 
12 s1=StarkConfig()
13 s2=StarkConfig()
14 ret1=s1.get_list_display()
15 print(ret1)
16 
17 ret2=s2.get_list_display()
18 print(ret2)
习题3
 1 class StarkConfig:
 2 
 3     list_display=[]
 4 
 5     def get_list_display(self):
 6         self.list_display.insert(0,33)
 7         return self.list_display
 8 
 9 class RoleConfig(StarkConfig):
10     list_display=[11,22]
11 
12 s1=StarkConfig()
13 s2=StarkConfig()
14 ret1=s1.get_list_display()
15 print(ret1)
16 
17 ret2=s2.get_list_display()
18 print(ret2)
习题4
 1 class StarkConfig:
 2 
 3     list_display=[]
 4 
 5     def get_list_display(self):
 6         self.list_display.insert(0,33)
 7         return self.list_display
 8 
 9 class RoleConfig(StarkConfig):
10     list_display=[11,22]
11 
12 s1=StarkConfig()
13 s2=StarkConfig()
14 ret1=s1.get_list_display()
15 print(ret1)
16 
17 ret2=s2.get_list_display()
18 print(ret2)
习题5
 1 class StarkConfig:
 2 
 3     list_display=[]
 4 
 5     def get_list_display(self):
 6         self.list_display.insert(0,33)
 7         return self.list_display
 8 
 9 class RoleConfig(StarkConfig):
10     list_display=[11,22]
11 
12 s1=StarkConfig()
13 s2=RoleConfig()
14 ret1=s1.get_list_display()
15 print(ret1)
16 
17 ret2=s2.get_list_display()
18 print(ret2)
习题6
 1 class StarkConfig:
 2 
 3     list_display=[]
 4 
 5     def get_list_display(self):
 6         self.list_display.insert(0,33)
 7         return self.list_display
 8 
 9 class RoleConfig(StarkConfig):
10     list_display=[11,22]
11 
12 s1=RoleConfig()
13 s2=RoleConfig()
14 ret1=s1.get_list_display()
15 print(ret1)
16 
17 ret2=s2.get_list_display()
18 print(ret2)
习题7
三. isinstance/issubclass/type
3.1 issubclass(翻译为是不是子集)检查第一个参数是否为第二个参数的子子孙孙
 1 class  Base:
 2     pass
 3 
 4 class Foo(Base):
 5     pass
 6 
 7 class Bar(Foo):
 8     pass
 9 
10 print(issubclass(Bar,Base))  #True  检查第一个参数是否为第二个参数的子子孙孙
3.2type  #判断当前对象是由哪个类创建的
1 class Foo:
2 #     pass
3 # obj=Foo()
4 # print(type(obj))  #<class '__main__.Foo'>
1 class Foo:
2     pass
3 obj=Foo()
4 print(obj)
5 if type(obj)==Foo:
6     print('obj对象是Foo类创建的')
7 else:
8     print('错误')  #obj对象是Foo类创建的
例子
 1 class Foo:
 2     pass
 3 
 4 class Bar:
 5     pass
 6 
 7 def func(*args):
 8     Foo_num=0
 9     Bar_num=0
10     for item  in args:
11         if type(item)==Foo:
12             Foo_num+=1
13         elif type(item)==Bar:
14             Bar_num+=1
15         else:
16             print('输入有误!')
17     return (Foo_num,Bar_num)
18 ret=func(Foo(),Foo(),Bar())
19 print(ret)  #(2, 1)
判断Foo类创建了几个对象,Bar类创建了几个对象
3.3isinstance  #检查第一个参数(对象)是否是第二个参数(类及父类)的实例
1 class Base:
2     pass
3 class Foo(Base):
4     pass
5 
6 obj=Foo()
7 print(isinstance(obj,Base))
四.方法还是函数
4.1用科学的方法判断是函数还是方法
 1 from types import MethodType,FunctionType
 2 def check(arg):
 3     '''
 4     检查arg是方法还是函数
 5     :param arg:
 6     :return:
 7     '''
 8     if isinstance(arg,MethodType):
 9         print('是一个方法')
10     elif isinstance(arg,FunctionType):
11         print('是一个函数')
12 
13 def func():
14     pass
15 class Foo:
16     def __init__(self,name):
17         self.name=name
18 
19     def func1(self):
20         print(self.name)
21 
22     @staticmethod
23     def func2():
24         pass
25 
26 check(func)
27 obj=Foo('haha')
28 
29 check(obj.func1)
30 check(obj.func2)
View Code
1 class Foo:
2     def f1(self):
3         pass
4     def f2(self):
5         pass
6 obj=Foo()
7 obj.f1()  #把f1当成一个方法,self自动传值
8 Foo.f1(obj)   # 把f1当成一个函数,手动传值
 1 class Foo:
 2     def f1(self):
 3         pass
 4     def f2(self):
 5         pass
 6     def f3(self):
 7         pass
 8     list_display=[f1,f2]
 9 obj=Foo()
10 Foo.list_display.append(obj.f3)
11 for item in Foo.list_display:
12     print(item)  #f1和f2是函数,f3是方法
View Code
总结:
用类调用的就是函数,用对象调用的就是方法
五.反射就是利用字符串形式的对象(模块)中操作(寻找/检查/删除/设置)成员。
 1 import handler
 2 handler.f1()
 3 while True:
 4     print('''
 5     系统支持的函数有:
 6     1.f1
 7     2.f2
 8     3.f3
 9     4.f4
10     5.f5
11     ''')
12     val=input('请输入要执行的函数')
13     if val=='f1':
14         handler.f1()
15     if val=='f2':
16         handler.f2()
17     if val=='f3':
18         handler.f3()
19     if val=='f4':
20         handler.f4()
21     if val=='f5':
22         handler.f5()
以前
 1 import handler
 2 handler.f1()
 3 while True:
 4     print('''
 5     系统支持的函数有:
 6     1.f1
 7     2.f2
 8     3.f3
 9     4.f4
10     5.f5
11     ''')
12     val = input('请输入要执行的函数')
13     if hasattr(handler,val):   #判断能否找到
14         func=getattr(handler,val)  #getattr('从哪里','找什么') 获取属性,根据字符串为参数,从模块中找到与之同名的成员
15         func()
16     else:
17         print('不存在')
反射实例(用模块做)
 1 class Foo:
 2     country='中国'
 3     def func(self):
 4         print('func')
 5 
 6 print(getattr(Foo,'country'))
 7 
 8 v=getattr(Foo,'func')
 9 v(Foo)   #根据字符串为参数,类中找到与之同名的成员
10 
11 obj=Foo()
12 v=getattr(obj,'func')()  #根据字符串为参数,从对象中找到与之同名的成员
总结:
因为一切皆对象,所以根据字符串为参数(第二个参数),从对象(第一个参数)中找到与之同名的成员
 1 class Foo:
 2     def login(self):
 3         print('d')
 4 
 5     def logout(self):
 6         print('z')
 7 
 8     def register(self):
 9         print('zc')
10 
11     def run(self):
12         choice_list =['login','logout','register']
13         print('''
14         '请输入要执行的功能:
15         1:登录
16         2.注销
17         3.注册
18         ''')
19         choice=int(input('请输入你的选择:'))
20         func=getattr(self,choice_list[choice-1])
21         func()
22 obj=Foo()
23 obj.run()
反射实例
反射的补充:(如果有特别多的判断时可以用)
getattr #根据字符串的形式,去对象中找成员
hasattr #根据字符串的形式,去对象中判断是否有成员
setattr #根据字符串的形式,动态设置一个成员(内存)
delattr ##根据字符串的形式,动态删除一个成员(内存)
 1 import xx
 2 v1=getattr(xx,'x1')
 3 v2=getattr(xx,'f1')
 4 v2('水火不容')
 5 
 6 v3=hasattr(xx,'x1')
 7 print(v3)
 8 v4=hasattr(xx,'f1')
 9 print(v4)
10 print(hasattr(xx,'dgdfb1'))
11 
12 
13 setattr(xx,'x2',999)
14 print(getattr(xx,'x2'))
15 
16 setattr(xx,'f2',lambda x:x-1)
17 print(getattr(xx,'f2'))
18 
19 delattr(xx,'x2')
20 print(getattr(xx,'x2'))
在模块中的应用
 1 class Foo:
 2     def __init__(self,a1):
 3         self.a1=a1
 4         self.a2=None
 5 obj=Foo(1)
 6 
 7 v=getattr(obj,'a1')
 8 print(v)
 9 
10 setattr(obj,'a2',2) #不建议用,如果要用上面要写self.a2=None,以便他人理解
在对象中的应用
六.什么后面可以加括号(判断一个东西是否可以被调用)
  类
  函数
  对象
  方法
calable判断一个东西是否可以被调用
 1 def func():
 2     pass
 3 class Foo:
 4     def __call__(self):
 5         pass
 6     def func(self):
 7         pass
 8     pass
 9 obj=Foo()
10 print(callable(func))  #True
11 print(callable(Foo))  #True
12 print(callable(obj))  #False 方法中加上__call__才会可调用
13 print(callable(obj.func))   #True
原文地址:https://www.cnblogs.com/shanghongyun/p/9560380.html