欢迎来到我的博客园

4.反射

一 isinstance,type,issubclass

class Animal:
    def eat(self):
        print("刚睡醒吃点东西")

class Cat(Animal):
    def play(self):
        print("猫喜欢玩")

c = Cat()
print(isinstance(c,Cat))#True
print(isinstance(c,Animal)) #True
print(type(c))#<class '__main__.Cat'>

type判断数据类型先判断好要计算的数据类型必须是int或者float. 这样的计算才有意义

def cul(a,b):
    if (type(a) == int or type(a) == float) and (type(b) == int or type(b) == float):
        return a + b
    else:
        print("对不起.你提供的数据不存在")
print(cul(1,2))

通过对象调用@classmethod的是方法,@statimethod的是函数

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 0x00000231A803DC50>>
print(Foo.chi)#<function Foo.chi at 0x00000231A81B4AE8>
print(f.static_method)#<function Foo.static_method at 0x00000231A81B4C80>
print(Foo.static_method)#function Foo.static_method at 0x00000231A81B4C80>
print(f.class_method)#<bound method Foo.class_method of <class '__main__.Foo'>>
print(Foo.class_method)#<bound method Foo.class_method of <class '__main__.Foo'>>

 结论:

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

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

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

from types import MethodType,FunctionType

def func():
    pass

print(isinstance(func,FunctionType))#True
print(isinstance(func,MethodType))#False

class Foo:
    def chi(self):
        print("我能吃")

    @staticmethod
    def static_method():
        pass

    @classmethod
    def class_method(cls):
        pass

obj = Foo()
print(type(obj.chi))#<class 'method'>
print(type(Foo.chi))#<class 'function'>
print(isinstance(obj.chi,MethodType))#True
print(isinstance(obj.chi,FunctionType))#False
print(isinstance(Foo.static_method,FunctionType))#True
print(isinstance(Foo.static_method,MethodType))#False
print(isinstance(Foo.class_method,FunctionType))#False
print(isinstance(Foo.class_method,MethodType)) #True

小题目

class Foo:
    @classmethod
    def func1(cls):
        pass
    @staticmethod
    def func2(self):
        pass
    def func3(self):
        pass
    def func4(self):
        pass

    lst = [func1,func2,func3]

obj = Foo()
#
Foo.lst.append(obj.func4)
#
for item in Foo.lst:
    print(isinstance(item,MethodType))
    print(item)

结果

False
<classmethod object at 0x000002090B72DDA0>
False
<staticmethod object at 0x000002090B72DE80>
False
<function Foo.func3 at 0x000002090B8A4EA0>
True
<bound method Foo.func4 of <__main__.Foo object at 0x000002090B72D8D0>>

反射

先创建master.py

def chi():
    print("大牛太能吃")
def he():
    print("大牛一次喝一桶")
def shui():
    print("大牛一睡睡一年")
def play():
    print("大牛不玩压缩包")
def sa():
    print("大牛很能撒谎")
def la():
    print("大牛喜欢拉二胡")

然后执行以下代码

import master

while 1:
    content = input("请输入你要测试的功能")
    if hasattr(master,content):
       s = getattr(master,content)
       s()
       print("有这个功能")

    else:
        print("没有这个功能")

 getattr可以从模块中获取内容, 也可以从类中获取内容, 也可以从对象中获取内容. 在python中一切皆为对象. 那可以这样认为. getattr从对象中动态的获取成员  

反射使用的常用函数:

hasattr()

用于判断对象是否包含对应的属性

getattr()

获取对象object的属性或者方法,如果存在打印出来,如果不存在,打印出默认值,默认值可选。
需要注意的是,如果是返回的对象的方法,返回的是方法的内存地址,如果需要运行这个方法,
可以在后面添加一对括号,getattr(变量名:命名空间,字符串:属于一个命名类的变量名)

setattr()

给对象的属性赋值,若属性不存在,先创建再赋值,setattr() 接收三个参数,命名空间,‘变量名’,变量值

delattr()

 删除 object对象 中的 name属性

class Foo:
    pass
f= Foo()
print(hasattr(f,"chi"))#False
setattr(f,"chi","123")
print(f.chi)#123

setattr(f,"chi",lambda x:x+1)
print(f.chi(3)) #4
print(f.chi)#<function <lambda> at 0x0000016718DE4D90>
print(f.__dict__)#{'chi': <function <lambda> at 0x00000192D2194D08>}

delattr(f,"chi")
print(hasattr(f,"chi"))#False

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

class Person:
    def __init__(self,name,laopo):
        self.name = name
        self.laopo = laopo

p= Person("宝宝","林志玲")

print(hasattr(p,"laopo"))
print(getattr(p,"laopo"))

setattr(p,"laopo","胡一菲")
setattr(p,"money",100000)

print(p.laopo)
print(p.money)

delattr(p,"laopo")
print(p.laopo)

  

  

posted @ 2019-02-24 14:57  等待の喵  阅读(169)  评论(0编辑  收藏