断点调式
在想要加断点的地方,用鼠标点击一下,可以看到一个红色圆圈。
变红的地方,程序执行到,就会暂停。
断点应该加载在报错之前。
控制台报错,点击能看懂的最后一行,光标会快速定位到错误代码,在错误代码上加断点,进行断点调式。
issubclass和isinstance
issubclass
判断第一个类是不是第二个类的子类,返回true或false
class Foo:
pass
class Bar(Foo):
pass
print(issubclass(Bar, Foo))
# True
isinstance
判断第一个参数是不是第二个参数的对象,返回true或false
class Foo:
pass
class Bar:
pass
f = Foo()
print(isinstance(f, Foo))
print(isinstance(f, Bar))
# True
# False
反射
一、什么是反射
反射:主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。
二、python面向对象中的反射
通过字符串的形式操作对象相关的属性。python中的一切事物都是对象,都可以使用反射。
四个可以实现自省的函数
适用于类和对象(一切皆对象,类本身也是一个对象)
hasattr():判断一个字符串属性是否在对象中,返回true或false
class Foo:
def run(self):
print('run...')
f = Foo()
print(hasattr(f, 'run'))
cmd = input('请输入命令:')
print(hasattr(f, cmd))
getattr():通过字符串获取属性或方法
class Foo:
def run(self):
print('run...')
f = Foo()
cmd = input('请输入命令:')
if hasattr(f, cmd):
run = getattr(f, cmd)
run()
else:
print('该命令不存在')
setattr():通过字符串来设置属性或方法
class Foo:
def run(self):
print('run...')
f = Foo()
def test(a):
print(a)
setattr(f, 'test', test)
print(f.__dict__)
delattr():通过字符串来删除属性或方法
class Foo:
def run(self):
print('run...')
f = Foo()
f.name = 'wu'
f.age = 18
f.sex = 'male'
cmd = input('请输入要删除的属性:')
print(f.__dict__)
delattr(f, cmd)
print(f.__dict__)
模块也是对象,也可以使用这四个方法
三、使用反射的好处
-
可以事先定义好接口,接口只有在被完成后才会真正执行,即事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能
-
使用自己写的模块,可以通过反射来判断模块中是否有我们要使用的属性或方法,有就执行,没有就报错
内置方法
__str__
:改变对象的字符串显示。可以理解为使用print函数打印一个对象时,会自动调用对象的__str__
方法。
class Student:
def __init__(self, name, age):
self.name = name
sels.age = age
def __str__(self):
return 'self.name'
s1 = Student('wu', 18)
print(s1)
# self.name
__repr__
:跟__str__
方法类似,在交互式命令下直接写变量名,会执行__repr__
__setattr__
:添加或修改属性的时候会触发
class Student:
def __init__(self, name):
self.name = name
def __setattr__(self, key, value):
print('不要赋值')
s1 = Student('wu')
# 不要赋值
__delattr__
:删除属性的时候会触发
class Student:
def __init__(self, name):
self.name = name
def __delattr(self, item):
print('不能删除属性')
s1 = Student('wu')
del s1.name
# 不能删除属性
__getattr__
:只有在使用点调用属性且属性不存在的时候才会触发
class Student:
def __init__(self, name):
self.name = name
def __getattr__(self, item):
return '没有这个属性'
s1 = Student('wu')
print(s1.age)
# 没有这个属性
__item__
系列:对象通过中括号取值、赋值、删除值得时候,会调用
class Student:
def __init__(self, name):
self.name = name
def __getitem__(self, item):
print(getattr(self, item))
def __setitem__(self, key, value):
print('obj[key]=wu赋值时,会执行我')
self.__dict__[key] = value
def __delitem__(self, key):
print('del obj[key]时,会执行我')
self.__dict__.pop(key)
s1 = Student('wu')
print(s1.__dict__)
s1['age'] = 18
print(s1.__dict__)
del s1['age']
print(s1.__dict__)
s1['name'] = 'xiaowu'
print(s1.__dict__)
# {'name': 'wu'}
# obj[key]=wu赋值时,会执行我
# {'name': 'wu', 'age': 18}
# del obj[key]时,会执行我
# {'name': 'wu'}
# obj[key]=wu赋值时,会执行我
# {'name': 'xiaowu'}
__call__
:__call__
方法的执行是由对象后加括号触发的,即:对象()。拥有此方法的对象可以像函数一样被调用。
class Student:
def __call__(self, *args, **kwargs):
print('run...')
s1 = Student()
s1()
# run...
__enter__
和__exit__
一个对象如果实现了__enter__
和__exit__
方法,那么这个对象就支持上下文管理协议,即with语句