博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python学习12-反射 判断函数与方法(转载)
阅读量:4703 次
发布时间:2019-06-10

本文共 6731 字,大约阅读时间需要 22 分钟。

一、三个内置函数

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

class Foo:

pass

class Zi(Foo):

pass

class Sun(Zi):

pass
print(issubclass(Zi,Foo)) #True
print(issubclass(Zi,Sun)) # False

issubclass

1 class Foo: 2     pass 3  4 class Zi(Foo): 5     pass 6  7 class Sun(Zi): 8     pass 9 print(issubclass(Zi,Foo))  #True10 print(issubclass(Zi,Sun))  # False

 

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

class Animal:

pass

class Cat(Animal):

pass

class BosiCat(Cat):

pass

c = Cat()

b = BosiCat()
print(type(c)) #<class '__main__.Cat'> 会准确说出c是一种Cat,不会说c是一种Animal

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))   #
会准确说出c是一种Cat,不会说c是一种Animal

 

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

class Animal:    passclass Cat(Animal):    passclass BosiCat(Cat):    passc = Cat()b = BosiCat()print(isinstance(c , Cat))     #判断c 是否是一种Catprint(isinstance(c,Animal))    #判断c 是否是一种Animalprint(isinstance(c,BosiCat)) 结果:TrueTrueFalse

 

二、判断函数与方法

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

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

简单来说:

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

方法和类或对象有绑定

# 区分函数和方法:

def func():

pass
print(func) # <function func at 0x10646ee18> 函数
class Foo:

def chi(self):

print("我是吃")
f = Foo()
print(f.chi) # <bound method Foo.chi of <__main__.Foo object at
0x10f688550>> 方法

函数和方法

1 def func(): 2  pass 3 print(func) # 
函数 4 class Foo: 5 6 def chi(self): 7 print("我是吃") 8 f = Foo() 9 print(f.chi) #
> 方法

class Foo:

def chi(self):
print("我是吃")
@staticmethod
def static_method():
pass
@classmethod
def class_method(cls):
pass

f = Foo()

print(f.chi) # <bound method Foo.chi of <__main__.Foo object at

0x10f688550>>

print(Foo.chi) # <function Foo.chi at 0x10e24a488>

print(Foo.static_method) # <function Foo.static_method at 0x10b5fe620>
print(Foo.class_method) # bound method Foo.class_method of <class
'__main__.Foo'>>

print(f.static_method) # <function Foo.static_method at 0x10e1c0620>

print(f.class_method) #<bound method Foo.class_method of <class
'__main__.Foo'>>

函数和方法

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          pass10 11 f = Foo()12 13 print(f.chi) # 
>15 16 print(Foo.chi) #
17 print(Foo.static_method) #
18 print(Foo.class_method) # bound method Foo.class_method of
>20 21 print(f.static_method) #
22 print(f.class_method) #
>

结论:

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

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

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

#官方判断方法:

通过types模块引入MethodType  FunctionType 来判断

from types import FunctionType, MethodType

class Car:

def run(self): # 实例方法
print("我是车, 我会跑")

@staticmethod

def cul():
print("我会计算")

@classmethod

def jump(cls):
print("我会jump")

c = Car()

实例方法:

# 1. 用对象.方法 方法
# 2. 类名.方法 函数
c = Car()
print(isinstance(c.run, FunctionType)) # False
print(isinstance(Car.run, FunctionType)) # True
print(isinstance(c.run, MethodType)) # True
print(isinstance(Car.run, MethodType)) # False

# 静态方法 都是函数

print(isinstance(c.cul, FunctionType)) # True
print(isinstance(Car.cul, FunctionType)) # True
print(isinstance(c.cul, MethodType)) # False
print(isinstance(Car.cul, MethodType)) # False

# 类方法都是方法

print(isinstance(c.jump, FunctionType)) # False
print(isinstance(Car.jump, FunctionType)) # False
print(isinstance(c.jump, MethodType)) # True
print(isinstance(Car.jump, MethodType)) # True

判断

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     @classmethod12     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)) # False22  print(isinstance(Car.run, FunctionType)) # True23  print(isinstance(c.run, MethodType)) # True24  print(isinstance(Car.run, MethodType)) # False25 26 # 静态方法 都是函数27  print(isinstance(c.cul, FunctionType)) # True28  print(isinstance(Car.cul, FunctionType)) # True29  print(isinstance(c.cul, MethodType)) # False30  print(isinstance(Car.cul, MethodType)) # False31 32 # 类方法都是方法33 print(isinstance(c.jump, FunctionType)) # False34 print(isinstance(Car.jump, FunctionType)) # False35 print(isinstance(c.jump, MethodType)) # True36 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 = color11         self.pai = pai12         self.price= price13 14     def fly(self):15         print('我的车会飞')16 17 c = Car('blue','丰田','18888')18 f = getattr(Car,"fly")    #操作对象是类,返回值相当于Car.fly19 print(f)      #
这里是函数,没有和类绑定,所以需要下面手动传值20 f(c) # f是函数,没有和类绑定,所以需要手动传值Car.fly(c) ,它是等价于c.fly()的21 22 #delattr(Car,"fly") #操作的是类,把类中fly方法删除了23 #c.fly() #报错,没有fly24 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方法

 

 

转载于:https://www.cnblogs.com/wuyufeng-9-14/p/10336885.html

你可能感兴趣的文章
MockObject
查看>>
BZOJ4516: [Sdoi2016]生成魔咒(后缀自动机)
查看>>
查看手机已经记住的WIFI密码
查看>>
最新版IntelliJ IDEA2019 破解教程(2019.08.07-情人节更新)
查看>>
C# 两个datatable中的数据快速比较返回交集或差集
查看>>
关于oracle样例数据库emp、dept、salgrade的mysql脚本复杂查询分析
查看>>
adb shell am 的用法
查看>>
iOS10 UI教程视图和子视图的可见性
查看>>
FindChildControl与FindComponent
查看>>
中国城市json
查看>>
android下载手动下载Android SDK
查看>>
C++学习:任意合法状态下汉诺塔的移动(原创)
查看>>
leetcode133 - Clone Graph - medium
查看>>
一点小基础
查看>>
UNET学习笔记2 - 高级API(HLAPI)
查看>>
"ORA-00942: 表或视图不存在 "的原因和解决方法[转]
查看>>
Oauth支持的5类 grant_type 及说明
查看>>
C#中用DateTime的ParseExact方法解析日期时间(excel中使用系统默认的日期格式)
查看>>
W3100SM-S 短信猫代码发送 上
查看>>
Linux IO模式及 select、poll、epoll详解
查看>>