当前位置: 移动技术网 > IT编程>脚本编程>Python > python记录_day18 反射 判断函数与方法

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

2018年11月10日  | 移动技术网IT编程  | 我要评论

2011年国考申论真题,卷筒组,奥村爱子

一、三个内置函数

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 print(issubclass(zi,sun))  # false
issubclass

 

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

 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类 (向上兼容)

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).

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

简单来说:

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

方法和类或对象有绑定

# 区分函数和方法:

 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>>    方法
函数和方法
 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 来判断

 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方法

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网