第一阶段:Python开发基础 day28 面向对象之反射与内置方法

一、断点调试

# 一定公民:只要可以吧一个东西赋值给一个变量,这个东西就叫一等公民

#在想要加断点的地方用鼠标点击一下,你会看到一个红色圆圈
#变红的地方,程序执行到,就会暂停
#断电应该加载报错之前
#绿色箭头表示快速跳到下一个断点执行

#控制台报错,点击你能看懂的最后一行,光标会快速定位到错误代码,在错误代码上放,加断电,断点调试
def test5():
    return 'lqz'
def test3():
    print('3333')
def test():
    def test2():
        test3()
        i=900
        i=test5()
        if i>100:
            print('大于100')
        # print(i)
        print(i)
    return test2
print('xxxx')
print('第一句话')
#这个函数内部出错
test()()
print('4444')

二、issubclass和ininstance方法

#判断第一个类是不是第二个类的子类,返回true或者false
# issubclass()
# class Foo:
#     pass
# class Bar(Foo):
#     pass
#
# class Tt(Bar):
#     pass
# print(Bar.__bases__)
# print(issubclass(Bar,Foo))
# print(issubclass(Tt,object))


#判断第一个参数是不是第二个参数的对象,返回true或者false
class Foo:
    pass
class Tt():
    pass

f=Foo()
print(isinstance(f,Foo))
print(isinstance(f,Tt))

三、反射

#用户输入一段字符串,执行该字符串对应的方法
# hasattr():判断一个属性是否在对象中,返回True或者False
# getattr():通过字符串获取属性或方法,如果获取到了,就会返回相应的属性或方法
# setattr():通过字符串来设置属性或方法
# delattr():通过字符串来删除属性或方法
class Foo:
    def run(self):
        print('run')
    def speak(self):
        print('speak')

p=Foo()
# print(Foo.__dict__)
# cmd=input('请输入命令:')
# #方案一:
# # print(Foo.__dict__[cmd])
# # Foo.__dict__[cmd](p)
# if hasattr(p,cmd):
#     run=getattr(p,cmd)
#     run()
# else:
#     print('该命令不存在')

#通过用户输入key和value往对象中赋值
# key=input('请输入key:')
# value=input('输入value:')
# setattr(p,key,value)
# print(p.age)

#动态的往对象中放方法
# def test(a):
#     print(a)
# print(p.__dict__)
# setattr(p,'test',test)
# print(p.__dict__)
# p.test(0)
#动态的删除属性

#原始的删除方法
# p.name='lqz'
# print(p.__dict__)
# del p.name
# print(p.__dict__)

#动态删除p中属性为变量a的属性
# p.name='lqz'
# p.age=18
# p.sex='male'
# a=input('请输入要删除的属性:')
# print(p.__dict__)
# delattr(p,a)
# print(p.__dict__)
#直接p.a是不对的
# del p.a

#删除对象中属性为name字符串的属性


#判断一下对象中有没有没有我输入的属性,如果有,打印
# p.name='lqz'
# p.age=18
# p.sex='male'
# cmd=input('请输入要查询的属性:')
# if hasattr(p,cmd):
#     a=getattr(p,cmd)
#     print(a)
# else:
#     print('该属性不存在')


#反射:通过字符串来获取,设置,删除对象中的属性或方法


#例子
class BlackMedium:
    feature='Ugly'
    def __init__(self,name,addr):
        self.name=name
        self.addr=addr

    def sell_house(self):
        print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼' %self.name)
    def rent_house(self):
        print('%s 黑中介租房子啦,傻逼才租呢' %self.name)

b1=BlackMedium('万成置地','回龙观天露园')


# print(b1.__dict__)
# print(hasattr(b1,'sell_house'))

# a='sell_house'
# getattr(b1,'sell_house')
# getattr(b1,a)()
# sell_house=getattr(b1,a)
# name=getattr(b1,'name')
# print(name)
# print(sell_house)

#删除属性或方法
# delattr(b1,'xxx')
# print(b1.__dict__)
# delattr(b1,'name')
# print(b1.__dict__)

#模块也是对象,也可以用四个方法
# import  os
# print(hasattr(os,'path1'))


#使用自己写的模块,通过反射来获取模块中是否有我要使用的属性或方法,如果有就执行,没有,就报错
# import utils

# utils.speak()
# if hasattr(utils,'speak'):
#     speak=getattr(utils,'speak')
#     speak()

#我以为它写完了
# utils.eat()
#更安全
# if hasattr(utils,'eat'):
#     eat=getattr(utils,'eat')
#     eat()
# else:
#     print('那个人还没写完呢')

四、内置方法

#学过的 __init__
#__str__:如果不重写__str__   print打印会打印出内存地址
#如果重写了,会打印出你想要的
#__repr__ 跟str类似,在交互式命令下直接写变量名,会执行__repr__
# class Foo:
#     def __init__(self,name):
#         self.name=name
#     def __str__(self):
#         return '['+self.name+']'
#
# f=Foo('nick')
# # print(f.__str__())
# #相当于上面那句
# print(f)
# l=[1,2,3]
# #本质也是调用list的__str__方法
# print(l)


#__setattr__,__delattr__,__getattr__(重要)
# 点拦截方法
#如果去对象中取属性,一旦取不到,会进入到__getattr__
#如果去对象中赋值属性,一旦取不到,会进入到__setattr__
#如果删除对象中的属性,会进入__delattr__
# class Foo:
#     def __init__(self,name):
#         self.name=name
#     # def __getattr__(self, item):
#     #     # print('xxxx')
#     #     return '你傻逼啊,没有这个字段'
#     # def __setattr__(self, key, value):
#     #     print('yyyyy')
#     def __delattr__(self, item):
#         print('zzzzz')
#
# f=Foo('nick')
# # print(f.name)
# # # print(f.age)
# print(f.__dict__)
# # print(f.name)
# # f.sex='male'
#
# del f.name
# print(f.__dict__)

#原来字典使用方式
# dict
# di=dict(name='lqz',age=18)
# # print(di)
# # print(di['name'])
# # print(di.name)
# # di.sex='male'
#
# #写一个类继承字典,让它可以 . 取值,可以中括号取值
class Mydict(dict):
    def __init__(self,**kwargs):
        #
        super().__init__(**kwargs)

    def __getattr__(self, item):
        #
        # print(item)

        return self[item]
    def __setattr__(self, key, value):
        self[key]=value



di=Mydict(name='lqz',age=18)
print(di['name'])
print(di.name)
di.sex='male'
di['sex']='male'
#
# # print(di['name'])
# # print(di.name)
# # di.sex=19
# # print(di.sex)
# di['sex']='male'
# print(di.sex)

#__item__系列  对象通过[] 中括号取值,赋值,删除值的时候,会调用
# class Foo:
#     def __init__(self, name):
#         self.name = name
#     def __getitem__(self, item):
#         name=getattr(self,item)
#         # print(name)
#         # print(self.__dict__[item])
#         return name
#         # return self.__dict__[item]
#     def __setitem__(self, key, value):
#         print('obj[key]=lqz赋值时,执行我')
#         self.__dict__[key] = value
#     def __delitem__(self, key):
#         print('del obj[key]时,执行我')
#         self.__dict__.pop(key)
#
# f=Foo('nick')
# print(f['name'])

#__call__   对象加括号会调用它
# class Foo:
#     def __call__(self):
#         print('xxxx')
#
# f=Foo()
# f()


#__enter__和__exit__
#上下文管理器,本质原来
# with open() as f:
#     pass


class Mydict():
    def __getattr__(self, item):
        print('xxx')
        return '该属性不存在'

m=Mydict()
print(m.name)

总结

进入内容:
   1 断点调试
      -在想要加断点的地方用鼠标点击一下,会变红色程序执行到这,会卡在这(如果是灰色,程序执行到这,不会停止),
      -点击向下的箭头:单步调试(程序一步一步走)
      -左侧有个绿色箭头:快速跳到下一个断电
   2 issubclass,ininstance(重点)
      -判断第一个类是不是第二个类的子类,返回true或者false
      -判断第一个参数是不是第二个参数的对象,返回true或者false
   3 反射
      -通过字符串获取对象的属性或方法
   4 类的内置方法(魔法方法)
      -__str__
      -__setattr__,__delattr__,__getattr__(重要)
      -__item__系列  对象通过[] 中括号取值,赋值,删除值的时候,会调用
      -__call__
posted @ 2019-09-16 18:39  foreversun92  阅读(149)  评论(0编辑  收藏  举报