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

python学习笔记:第18天 面向对象04-反射

程序员文章站 2022-05-08 18:19:02
[TOC] issubclass和isinstance issubclass:可以判断一个类是否另一个类的子类。 type:然后我们来看type. type在前⾯的学习期间已经使⽤过了. type(obj) 表⽰查看obj是由哪个类创建的 isinstance:判断一个对象是否是某个类的实例 我们再 ......

目录

issubclass和isinstance

  • issubclass:可以判断一个类是否另一个类的子类。
# issubclass

class a:
    pass

class b(a):
    pass

class c(b):
    pass

print(issubclass(b, a))
print(issubclass(c, b))
print(issubclass(c, a))

# 结果:
# true
# true
# true
  • type:然后我们来看type. type在前⾯的学习期间已经使⽤过了. type(obj) 表⽰查看obj是由哪个类创建的
  • isinstance:判断一个对象是否是某个类的实例
class foo:
pass
obj = foo()
print(obj, type(obj)) # 查看obj是由那个类创建的

我们再来看一个加法函数函数:

# type和issubclass

# 定义一个函数,计算两个数的和
def cal(a, b):
    if (type(a) == int or type(b) == float) and (type(b) == int or type(b) == float):
        return a + b
    else:                       # 这路先进行了类型的判断,如果不是int或者是float类型的则不进行计算
        return '不能帮你计算'
    
print(cal(10, 20))
print(cal(10, '胡辣汤'))

# 结果:
# 30
# 不能帮你计算

像这种处理可以使用isinstance来处理,isinstance咳哟判断一个对象是否是一个类的实例或者是其父类的实例:

def cal (a, b):
    if isinstance(a, (int, float)) and isinstance(b, (int, float)):
        return a + b
    else:
        return '不能帮你计算'

print(cal(10.3, 20))
print(cal(10, '胡辣汤'))

# 结果:
# 30.3
# 不能帮你计算

总结一下:

内置函数 描述及使用场景 使用方法
issubclass 判断一个类是否是另一个类的子类 issubclass(cls, class_or_tuple)
type 查看一个对象的具体类型,不会查找父类 type(obj)
isinstance 判断一个对象是否是某个对象的实例,但是isinstance没有type那么精准,他会向上查找父类 isinstance(obj, class_or_tuple)

区分函数和方法

from types import functiontype, methodtype

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

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

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


# 实例方法:
#     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
  • 类⽅法. 不论任何情况, 都是⽅法.
  • 静态⽅法, 不论任何情况. 都是函数.
  • 实例⽅法, 如果是实例访问. 就是⽅法. 如果是类名访问就是函数.

反射

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

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

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

setattr(obj, str, value) 把obj中的str成员设置成value. 注意. 这⾥的value可以是值, 也可以是函数或者⽅法

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

  • hasattr:判断某个对象中是否存在指定的属性或者方法
  • getattr:获取某个对象中指定的方法
hasattr(obj, name, /)
    return whether the object has an attribute with the given name.
    
    this is done by calling getattr(obj, name) and catching attributeerror.

setattr(obj, name, value, /)
    sets the named attribute on the given object to the specified value.
    
    setattr(x, 'y', v) is equivalent to ``x.y = v''
class foo:
    def func1(self):
        print('我是func1函数')

    def func2(self):
        print('我是func2函数')
        
    def func3(self):
        print('我是func3函数')
        
f = foo()

fn = input('请输入你要测试的函数:')
if hasattr(f, fn):                                      # 先判断f中是否有fn属性
    func = getattr(f, fn)                               # 确认有这个属性在从对象中获取这个属性
    func()
else:
    print('没有这个功能')

# 结果:
# 请输入你要测试的函数:func1
# 我是func1函数
  • setattr:设置某个对象的属性(变量或者是方法)
setattr(f, 'func3', lambda:print('我是自定义函数'))         # 设置自定义方法
f.func3()

setattr(f, 'name', 'zzc')                                   # 设置自定义属性
print(f.name)

# 结果:
# 我是自定义函数
# zzc
  • delattr:删除对象中指定的属性
delattr(foo, 'func2')
f.func2()                               # 此时foo中的func2方法已经被删除了,这里执行会抛出异常

---------------------------------------------------------------------------
attributeerror                            traceback (most recent call last)
<ipython-input-5-dd69df692558> in <module>
----> 1 f.func2()

attributeerror: 'foo' object has no attribute 'func2'