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成员删除掉

注意, 以上操作都是在内存中进行的. 并不会影响你的源代

 

 

posted @ 2018-12-20 19:58  言吾  阅读(171)  评论(0编辑  收藏  举报