类的高阶、反射、魔法方法

一、issubclass和isinstance

issubclass:判断第一个参数是不是第二个参数的子类,返回True或者False

# issubclass

class Foo:
    pass
class Bar(Foo):
    pass
class Tt(Bar):
    pass
print(Bar.__bases__)
print(issubclass(Bar, Foo))
print(issubclass(Tt, objcet)

isinstance:判断第一个参数是不是第二个参数的对象,返回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往对象中赋值
p = Foo()
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中属性为变量a的属性
p.name = 'lqz'
p.age = 19
p.sex = 'male'
a = input('请输入要删除的属性:')
print(p.__dict__)
delattr(p, a)
print(p.__dict__)

三、内置方法

__str__:重写之后print打印的是__str__的返回值,不重写返回的是对象的内存地址

__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)  # 相当于上面那句

__setattr__, __delattr__, __getattr__

点拦截方法:

如果去对象中取属性,一旦取不到,会进入到__getattr__

如果去对象中赋值属性(添加or修改),会进入到__setattr__

如果删除对象中的属性,会进入__delattr__

class Foo:
    def __init__(self, name):
        self.name = name
    def __getattr__(self, item):
        return '你傻逼阿, 没有这个字段'
	def __setattr__(self, key, value):
        # self.key = value   无限递归
        self.__dict__[key] = value
    def __delattr__(self, item):
        # del self.item    无限递归
        self.__dict__.pop(item)
f1 = Foo(10)

__item__系列 对象通过[]中括号取值,赋值,删除值的时候,会调用

class Foo:
	def __init__(self, name):
        self.name = name
    def __getitem__(self, item):
        name = getattr(self, 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)

__call__ :对象加括号会调用它

class Foo:
    def __call__(self):
        print('xxxx')
        
f = Foo()
f()

__enter__和__exit__

上下文管理器

四、断点调试

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

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

控制台报错,点击你能看懂的最后一行,光标会快速定位到错误代码,在错误代码上放,加断电,断点调试

posted @ 2019-09-02 20:06  17vv  阅读(172)  评论(0编辑  收藏  举报