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

2018-11-12 06:53:23来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

一、三个内置函数

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

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:queue消息队列

下一篇:djano-模板层基础知识