1. 程式人生 > >python記錄_day18 反射 判斷函式與方法

python記錄_day18 反射 判斷函式與方法

一、三個內建函式

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