特殊方法补充以及反射
一.特殊方法补充
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中
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中
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 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)
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)
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)
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)
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)
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)
三. 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)
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)
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是方法
总结:
用类调用的就是函数,用对象调用的就是方法
五.反射就是利用字符串形式的对象(模块)中操作(寻找/检查/删除/设置)成员。
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
改变世界,改变自己!