函数高阶

1. 断点调试

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

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

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

2. issubclass / isinstance

# issubclass()
# 判断第一个类是不是第二个类的子类,返回true或false

class Foo:
    pass
class Bar(Foo):
    pass

class T(Bar):
    pass
print(Bar.__bases__)
print(issubclass(Bar,Foo))
print(issubclass(T,object))


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

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

03 反射

# 用户输入一段字符串,执行该字符串对应的方法
# 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'))

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

4. 内置方法

# 学过的__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__)

# 原来字典使用方式
dic = dict(name = 'lqz',age = 18)
print(dic)
print(dic['name'])
# print(dic.name)
# dic.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

dic = Mydict(name = 'iqz',age = 18)
print(dic['name'])
print(dic.name)
dic.sex = 'male'
dic['sex'] = 'male'

print(dic['name'])
print(dic.name)
dic.sex=19
print(dic.sex)
dic['sex']='male'
print(dic.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)
原文地址:https://www.cnblogs.com/yushan1/p/11449001.html