isinstance type issubclass 区分方法和函数 反射:hasattr getattr setattr delattr
isinstance type issubclass
isinstance: 判断你给对象是否是xx类型的. (向上判断)
type: 返回xxx对象的数据类型
issubclass: 判断xxx类是否xxx的子类
class Animal:
def eat(self):
print("刚睡醒吃点儿东西")
class Cat(Animal):
def play(self):
print("猫喜欢玩儿")
c = Cat()
print(isinstance(c, Cat)) # c是一只猫 这里判断c是不是Cat类里面的
print(isinstance(c, Animal)) # 向上判断 这里判断c是不是Animal类里面的
a = Animal()
print(isinstance(a, Cat)) # 不能向下判断
print(type(a)) # 返回 a的数据类型
print(type([]))
print(type(c)) # 精准的告诉你这个对象的数据类型
# 判断.xx类是否是xxxx类的子类
print(issubclass(Cat, Animal))
print(issubclass(Animal, Cat))
# 应用
def cul(a, b): # 此函数用来计算数字a和数字b的相加的结果
# 判断传递进来的对象必须是数字. int float
if (type(a) == int or type(a) == float) and (type(b) == int or type(b) == float):
return a + b
else:
print("对不起. 您提供的数据无法进行计算")
print(cul(a, c))
如何区分方法和函数(代码)
在类中:
实例方法
如果是类名.方法 函数
如果是对象.方法 方法
类方法: 都是方法
静态方法: 都是函数
from types import MethodType, FunctionType
isinstance()
def func(): print("我是函数") class Foo: def chi(self): print("我是吃") # print(func) # <function func at 0x0000000001D42E18> f = Foo() # f.chi() print(f.chi) # <bound method Foo.chi of <__main__.Foo object at 0x0000000002894A90>>
# 野路子:
这里打印了方法或者函数的名字
打印的结果中包含了function. 函数
# method . 方法
我们的类也是对象.
这个对象: 属性就是类变量
方法就是类方法
class Person: def chi(self): print("我要吃鱼") @classmethod def he(cls): print("我是类方法") @staticmethod def pi(): print("泥溪镇地皮") p = Person() Person.chi(1) # 不符合面向对象的思维
#这里直接使用类名.方法 其实是没有经过对象的,所以不符合面向对象的思维,虽然这里可以使用,但是千万不要用
print(p.chi) # <bound method Person.chi of <__main__.Person object at 0x00000000028C4B70>> print(Person.chi) # <function Person.chi at 0x00000000028989D8> 实例方法: 1. 如果使用 对象.实例方法 方法 2. 如果使用 类.实例方法 函数 print(Person.he) # <bound method Person.he of <class '__main__.Person'>> print(p.he) # <bound method Person.he of <class '__main__.Person'>> 类方法都是 方法 print(Person.pi) # <function Person.pi at 0x0000000009E7F488> print(p.pi) # <function Person.pi at 0x0000000009E7F488> 静态方法都是函数 # 记下来 from types import FunctionType, MethodType # 方法和函数 导入的是函数 和方法模块 from collections import Iterable, Iterator #可迭代的 迭代器 实例:
class Person: def chi(self): # 实例方法 print("我要吃鱼") @classmethod def he(cls): print("我是类方法") @staticmethod def pi(): print("泥溪镇地皮") p = Person() print(isinstance(Person.chi, FunctionType)) # True print(isinstance(p.chi, MethodType)) # True print(isinstance(p.he, MethodType)) # True print(isinstance(Person.he, MethodType)) # True print(isinstance(p.pi, FunctionType)) # True print(isinstance(Person.pi, FunctionType)) # True
在这里,就可以得出结论:
在类中:
实例方法 如果是类名.方法 函数
如果是对象.方法 方法
类方法: 都是方法
静态方法: 都是函数
from types import MethodType, FunctionType
isinstance()
___________________________________________________________________________
反射.
首先, 我们看这样⼀个需求, 说, 有个大牛, 写了⼀堆特别牛B的代码. 然后放在了⼀个py ⽂件里(模块), 这时, 你想⽤这个大⽜写的东西. 但是呢. 你⾸先得知道⼤牛写的这些代码都是 干什么用的. 那就需要你把⼤牛写的每一个函数跑一下. 摘一摘⾃己想用的内容. 来咱们模拟 这样的需求, 首先, ⼤牛给出⼀个模块.
import master # 报错不用管 这里导入模块
print("""
1. chi: 大牛特别能吃
2. he: 大牛特别能喝
3. shui: 大牛特别能睡
4. play: 大牛特别能玩儿
5. sa: 大牛很喜欢撒谎
""")
while 1:
content = input("请输入你要执行的函数:")
if content == "1":
master.chi()
elif content == "2":
master.he()
elif content =="3":
master.shui()
elif content == "4":
master.play_1()
elif content == "5":
master.sa()
写是写完了. 但是.....如果⼤牛现在写了100个功能呢? 你的判断要100次么? 太累 了吧. 现有的知识解决不了这个问题. 那怎么办呢? 注意看. 我们可以使⽤反射来完成这样的功能. 非常的简单. 想想. 这里我们是不是让用户输入要执行的功能了. 那这个功能就是对应 模块里的功能. 那也就是说. 如果能通过字符串来动态访问模块中的功能就能解决这个问题. 好了. 我要告诉你. 反射解决的就是这个问题. 为什什么叫反射? 反着来啊. 正常是我们先引入 模块, 然后⽤模块去访问模块里的内容. 现在反了. 我们⼿动输入要运行的功能. 反着去模块 里找. 这个就叫反射
import master #导入模块
while 1:
content = input("请输入你要测试的功能:") # 用户输入的功能是一个字符串
# 判断 xxx对象中是否包含了xxxxx
if hasattr(master, content):
xx = getattr(master, content)
xx()
print("有这个功能")
else:
print('没有这个功能')
关于反射, 其实⼀一共有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成员删除掉
注意, 以上操作都是在内存中进行的. 并不会影响你的源代码
# 对于模块而言可以使用getattr, hasattr, 同样对于我们的对象也可以执行类似的操作 class Person: def __init__(self, name, laopo): self.name = name self.laopo = laopo p = Person("宝宝", "林志玲") print(hasattr(p, "laopo")) # print(getattr(p, "laopo")) # p.laopo setattr(p, "laopo", "胡一菲") # p.laopo = 胡一菲 setattr(p, "money", 100000000000) # p.money = 100000000 print(p.laopo) print(p.money) delattr(p, "laopo") # 把对象中的xxx属性移除. != p.laopo = None print(p.laopo)#####会报错
______________________
True
林志玲
胡一菲
100000000000
最后移除了laopo这个属性,所以会报错
关于反射, 其实一共有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成员删除掉
注意, 以上操作都是在内存中进行的. 并不会影响你的源代