断点调式和面向对象进阶

断点调式

在想要加断点的地方,用鼠标点击一下,可以看到一个红色圆圈。

变红的地方,程序执行到,就会暂停。

断点应该加载在报错之前。

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

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__)

模块也是对象,也可以使用这四个方法

三、使用反射的好处

  1. 可以事先定义好接口,接口只有在被完成后才会真正执行,即事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能

  2. 使用自己写的模块,可以通过反射来判断模块中是否有我们要使用的属性或方法,有就执行,没有就报错

内置方法

__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语句

posted @ 2019-09-02 21:34  云台三落  阅读(200)  评论(0编辑  收藏  举报