19.方法和函数,反射

今日主要内容

 1.issubclass,type,isinstance
        issubclass  判断xxx类是否是xxxx的子类
        type 给出xxx 的数据类型   给出创建这个对象的类
        isinstance  判断xxx对象是否是xxx类型的
    2. 如何分辨方法和函数.
            在外面定义的函数一定是函数
            在类中:
                1. 实例方法: 如果是对象访问.方法,, 如果是类名访问是函数
                2. 静态方法: 都是函数
                3. 类方法: 都是方法
            如果想要用程序来判断. 需要引入两个模块
            from types import FunctionType, MethodType
            isinstance()

        3. 反射(重点)
            仅限于内存层面
            重点:
            hasattr(obj, str) 判断对象中是否包含了xxx(str)
            getattr(obj, str) 从对象中获取xxxx(str)
            次重点:
            setattr(obj, str, value) 给对象设置xxxx(str)属性值(value)
            delattr(obj, str) 从对象中删除xxxxx(str)信息
            这些操作都是在内存中进行的,并不会影响源代码

 

1.issubclass

判断前一个类是否是后一个的子类

class Animal:
    pass
class Cat(Animal):
    pass
class BosiCat(Cat):
    pass

print(issubclass(Cat,Animal))    #判断前一个类是否是后一个
print(issubclass(BosiCat,Animal))   #父类的父类也是
print(issubclass(Animal,Cat))  #父类不包含在子类中

isinstance 判断xxx对象是否是xxx类型的

class Animal:
    pass

class Cat(Animal):
    pass

class BoSiCat(Cat):
    pass
a = Animal()
print(isinstance(a,Animal))#自己的类可以判断
print(isinstance(a,Cat))#子类不能判断

c =BoSiCat()
print(isinstance(c,Animal))  #子类的对象可以当成父类的类型来看
# isinstance()判断的对象是否是XXX家族体系的内容,子类没有找到可以往上找,找父类的


lst = '马化腾'
print(type(lst.__iter__()))   比如说字符串就是属于字符串类型的

 

type 给出xxx 的数据类型 给出创建这个对象的类

 

class Animal:
    pass
class Cat(Animal):
    pass
class BosiCat(Cat):
    pass
c = Cat()
print(type(c))
比较精准的给出对象的类

type(obj)   表示查看obj是由哪个类创建的
class foo:
    pass
obj = foo()
print(obj,type(obj)) 查看obj的类


class Boy:
    pass
class Girl:
    pass

def func(*args):
    b = 0
    g = 0
    for obj in args:
        if type(obj) == Boy:
            b += 1
        elif type(obj) == Girl:
            g += 1
    return b ,g
ret =func(Boy(),Girl(),Boy(),Girl(),Boy(),Girl())
print(ret)
帮助我们判断xxx是xxx数据类型的


def add(a,b):
    if (type(a) == int or type(a) == float) and (type(b) == int or type(b) == float):
        return a + b
    else :
        print('输的啥瘪犊子玩意儿')
print(add(3,4))
print(add(5,4.8))
print(add('妈卖批',3))
计算a + b 的结果并返回,两个数相加

如何分辨方法和函数

1.通过打印语句来判断

方法和函数的区别
def func():
    pass
print(func)#<function func at 0x000001C54CD49598>


class foo:
    def func1(self):
        pass
fun = foo()
print(fun.func1)#<bound method foo.func1 of <__main__.foo object at 0x000001D3F3754F60>>
方法和函数的区别简单的可以通过打印一下就能看到,但是可能会出现差错

class Person:
    def chi(self):
        print('中午吃盖浇饭吧')
    @staticmethod
    def da():
        pass
    @classmethod
    def gan(cls):
        pass
huang = Person()
print(huang.chi)  #方法
print(huang.da)  #函数
print(huang.gan)  #方法
print(Person.chi)#函数
print(Person.da)#函数
print(Person.gan)#方法
观察可以得到结论
1.类方法.不管任何时候都是方法
2.静态方法,不管任何时候都是函数
3.实例方法,如果是实例访问,就是方法,如果类名访问就是函数

以上方法是用打印语句直接进行判断

 

2.通过程序语句来执行

# 借助于types模块
from types import MethodType,FunctionType

# 所有的函数都是FunctionType的实例
# 所有的方法都是MethodType的实例
# def func():
#     pass
# print(isinstance(func,FunctionType))
# print(isinstance(func,MethodType))  判断是函数的实例还是方法的实例

#
# class Person:
#     def chi(self):
#         print('中午吃盖浇饭吧')
#     @staticmethod
#     def da():
#         pass
#     @classmethod
#     def gan(cls):
#         pass
# huang = Person()
# # print(type(huang.chi))
# # print(type(Person.chi))
# print(type(huang.gan))
# print(isinstance(Person.chi,FunctionType))
# print(isinstance(Person.chi,MethodType))
# print(isinstance(Person.gan, MethodType))

# from types import MethodType
# 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()
# print(isinstance(obj.func1, MethodType))
# Foo.lst.append(obj.func4)
# for item in Foo.lst:
#     print(isinstance(item,MethodType))

 

模块部分的反射

1,在master.py文件下写下各种功能和函数

假设写下这样的

def chi():
    print('我喜欢吃肉夹馍')

def he():
    print('我喜欢喝汉斯小木屋')

def piao():
    print('我不喜欢嫖女人')

def du():
    print('我只赌两块的')

name = '我要成为大牛'

 

在另一个文件中进行调用和测试

import master

while 1:
    print('''我还是菜鸟的时候写了很多东西
    chi
    he
    piao
    du
    ''')
    val = input('请输入你想测试我的啥程序')
    if hasattr(master,val):#判断有没有
        attr = getattr (master,val)    #从master对象或者模块中找bbb功能  找这个val输入的字符串的函数,也可能是变量
        if callable(attr):  #判断能不能被调用
            attr()
        else:
            print(attr)
    else:
        print('我没有写这个功能')


# func= getattr(aaa,bbbb)  从aaa对象或者模块中找bbb功能  找这个bbb字符串的函数

print(master.chi)
setattr(master, "chi", lambda x: x + 1)#把chi 函数换为lambda
print(master.chi)

delattr(master, "la") # 删除xxx
master.la()

面向对象的反射

 

son:
    def __init__(self,name):
        self.name = name

    def chi(self):
        print('人喜欢吃东西')

p = Person('刘伟')
p.chi()#直接调用

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

    def chi(self):
        print('人喜欢吃东西%s'%self.name)
p = Person('刘伟')
func = getattr(p,'chi')
func()
val = input('请输入你想让刘伟执行的动作')
if hasattr(p,val):
    getattr(p,'name')
    func = getattr(p,val)
    func()


补充
setattr(p,'name','大秧歌')
print(p.name)  #替换
setattr(p,'age',18)
print(p.age)#动态给对象设置属性和值  很少用,慎用
如果要使用,在属性函数里添加self.age=none
delattr(p,'age')
print(p.age)

 

posted on 2018-10-15 19:01  小王子QAQ  阅读(44)  评论(0)    收藏  举报