欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python记录_day18 反射 判断函数与方法

程序员文章站 2022-12-23 17:48:46
一、三个内置函数 1、issubclass(a, b) 判断a类是否是b类的子类 1 class Foo: 2 pass 3 4 class Zi(Foo): 5 pass 6 7 class Sun(Zi): 8 pass 9 print(issubclass(Zi,Foo)) #True 10 ......

一、三个内置函数

1、issubclass(a, b)  判断a类是否是b类的子类

python记录_day18 反射  判断函数与方法
 1 class foo:
 2     pass
 3 
 4 class zi(foo):
 5     pass
 6 
 7 class sun(zi):
 8     pass
 9 print(issubclass(zi,foo))  #true
10 print(issubclass(zi,sun))  # false
issubclass

 

2、type(对象)   返回该对象的数据类型,精确识别(即不向上兼容)  

python记录_day18 反射  判断函数与方法
 1 class animal:
 2     pass
 3 
 4 class cat(animal):
 5     pass
 6 
 7 class bosicat(cat):
 8     pass
 9 
10 c = cat()    
11 b = bosicat()
12 print(type(c))   #<class '__main__.cat'>  会准确说出c是一种cat,不会说c是一种animal
type

 

3、isinstance(对象,类)   判断xx对象是否是xxx类 (向上兼容)

python记录_day18 反射  判断函数与方法
class animal:
    pass

class cat(animal):
    pass

class bosicat(cat):
    pass

c = cat()
b = bosicat()

print(isinstance(c , cat))     #判断c 是否是一种cat
print(isinstance(c,animal))    #判断c 是否是一种animal
print(isinstance(c,bosicat))
 
结果:
true
true
false
isinstace

 

二、判断函数与方法

python官方定义:

函数function —— a series of statements which returns some value to a caller. it can also be passed zero or more arguments which may be used in the execution of the body.

方法method —— a function which is defined inside a class body. if called as an attribute of an instance of that class, the method will get the instance object as its first argument (which is usually called self).

从定义看,函数就相当于一个数学公式,它不与其他东西相互关联,传递相应的参数就能用。而方法是,定义在类内部的函数,并且这个函数和类或类的实例对象有某种关联,访问时会自动传递一个参数作为第一参数。

简单来说:

函数没和类或对象进行绑定;

方法和类或对象有绑定

# 区分函数和方法:

python记录_day18 反射  判断函数与方法
 1 def func():
 2  pass
 3 print(func) # <function func at 0x10646ee18>  函数
 4 class foo:
 5 
 6  def chi(self):
 7  print("我是吃")
 8 f = foo()
 9 print(f.chi) # <bound method foo.chi of <__main__.foo object at
10 0x10f688550>>    方法
函数和方法
python记录_day18 反射  判断函数与方法
 1 class foo:
 2      def chi(self):
 3          print("我是吃")
 4      @staticmethod
 5      def static_method():
 6          pass
 7      @classmethod
 8      def class_method(cls):
 9          pass
10 
11 f = foo()
12 
13 print(f.chi) # <bound method foo.chi of <__main__.foo object at
14 0x10f688550>>
15 
16 print(foo.chi) # <function foo.chi at 0x10e24a488>
17 print(foo.static_method) # <function foo.static_method at 0x10b5fe620>
18 print(foo.class_method) # bound method foo.class_method of <class
19 '__main__.foo'>>
20 
21 print(f.static_method) # <function foo.static_method at 0x10e1c0620>
22 print(f.class_method) #<bound method foo.class_method of <class
23 '__main__.foo'>>            
函数和方法

结论:

1. 类方法. 不论任何情况, 都是方法.

2. 静态方法, 不论任何情况. 都是函数

3. 实例方法, 如果是实例访问. 就是方法. 如果是类名访问就是函数.

#官方判断方法:

通过types模块引入methodtype  functiontype 来判断

python记录_day18 反射  判断函数与方法
 1 from types import functiontype, methodtype
 2 
 3 class car:
 4     def run(self): # 实例方法
 5         print("我是车, 我会跑")
 6 
 7     @staticmethod
 8     def cul():
 9         print("我会计算")
10 
11     @classmethod
12     def jump(cls):
13         print("我会jump")
14 
15 c = car()
16 
17 实例方法:
18 #     1. 用对象.方法   方法
19 #     2. 类名.方法     函数
20 c = car()
21  print(isinstance(c.run, functiontype)) # false
22  print(isinstance(car.run, functiontype)) # true
23  print(isinstance(c.run, methodtype)) # true
24  print(isinstance(car.run, methodtype)) # false
25 
26 # 静态方法 都是函数
27  print(isinstance(c.cul, functiontype)) # true
28  print(isinstance(car.cul, functiontype)) # true
29  print(isinstance(c.cul, methodtype)) # false
30  print(isinstance(car.cul, methodtype)) # false
31 
32 # 类方法都是方法
33 print(isinstance(c.jump, functiontype)) # false
34 print(isinstance(car.jump, functiontype)) # false
35 print(isinstance(c.jump, methodtype)) # true
36 print(isinstance(car.jump, methodtype)) # true
判断

 

三、反射(重点)

关于反射, 其实一共有4个函数:

1. hasattr(obj, str)   判断obj中是否包含str成员

2. getattr(obj,str)    从obj中获取str成员

3. setattr(obj, str, value)     把obj中的str成员设置成value      这里的value可以是值, 也可以是函数或者方法

4. delattr(obj, str) 把obj中的str成员删除掉

注意:

obj可以是模块,类,实例对象

以上操作都是在内存中进行的, 并不会影响你的源代码,但是在同一个py文件中,你通过反射修改了类,是会影响到其他对象的。

 

 1 #反射用到的四个函数,常用的是hasattr 和getattr
 2 # setattr(a,b,c)  a是要操作的对象,b是操作对象中的成员字符串形式,c是修改的值
 3 # getattr(a,b)     有返回值,返回值形式a.b    a是要操作的对象,b是操作对象中的成员字符串形式
 4 #delattr(a,b)      a是要操作的对象,b是操作对象中的成员字符串形式
 5 #hasatter(a,b)     a是要操作的对象,b是操作对象中的成员字符串形式
 6 
 7 class car:
 8 
 9     def __init__(self,color,pai,price):
10         self.color = color
11         self.pai = pai
12         self.price= price
13 
14     def fly(self):
15         print('我的车会飞')
16 
17 c = car('blue','丰田','18888')
18 f = getattr(car,"fly")    #操作对象是类,返回值相当于car.fly
19 print(f)      #<function car.fly at 0x0000000001ea9d08> 这里是函数,没有和类绑定,所以需要下面手动传值
20 f(c)       # f是函数,没有和类绑定,所以需要手动传值car.fly(c) ,它是等价于c.fly()的
21 
22 #delattr(car,"fly")    #操作的是类,把类中fly方法删除了
23 #c.fly()     #报错,没有fly
24 
25 c2 =car("yellow","bmw",20000)
26 
27 def fly():
28     print("通过对象c修改fly方法")
29     
30 setattr(c,"fly",fly)         #并没有改变类中的内容,相当于在当前对象中创建了一个fly方法,一个对象是不可能有修改类的权限的
31 c.fly()       #通过对象c修改fly方法
32 c2.fly()     #我的车会飞
33 c3 = car("blue","奔驰",88888)
34 c3.fly()      #我的车会飞
35 setattr(car,'fly',lambda self:print('通过类名,修改fly方法')) #通过类名修改fly方法
36 c.fly()     #通过对象c修改fly方法
37 c2.fly()   #通过类名,修改fly方法
38 c3.fly()  #通过类名,修改fly方法
39 c4 = car("red","悍马",66666)
40 c4.fly()     #通过类名,修改fly方法