zoukankan      html  css  js  c++  java
  • 面向对象高级A(反射,拦截方法)

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

    断点调试

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

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

    断点应该加在报错之前,在错误代码上放断点进行调试

    向下绿色箭头是单步调试

    右下角色绿色三角形是快速调到下一个断点执行

    控制台报错,点击你能看懂的最后一行,光标会定位到错误代码

    issubclass()

    判断第一个类是不是第二个类的子类,返回true或者false

    class Foo:
        pass
    
    class Bar(Foo):
        pass
    
    class Tt(Bar):
        pass
    
    print(Tt.__bases__) #(<class '__main__.Bar'>,)
    print(issubclass(Bar, Foo)) # True
    print(issubclass(Tt, Foo)) # True
    

    isinstance()

    判断第一个参数是不是第二个参数的对象,返回True或者False

    class Foo:
        pass
    class Tt:
        pass
    f = Foo()
    print(isinstance(f, Foo)) # true
    print(isinstance(f, Tt)) # false
    

    反射

    hasattr(): 判断一个属性是否在对象中,返回true或者false

    getattr():通过字符串获取属性或方法,如果获取到了,就会返回相应的属性或方法

    settattr():通过字符串来设置属性或方法

    delattr():通过字符串来删除属性或方法

    class Foo:
        def run(self):
            print('run')
        def speak(self):
            print('speak')
    p = Foo()
    
    cmd = input('请输入命令')
    
    if hasattr(p, cmd):
        cmd1 = getattr(p, cmd)
        cmd1()
    else:
        print('该命令不存在')
        
    ‘’‘
    请输入命令:run
    run
    
    请输入命名:a
    该命令不存在
    ’‘’
    
    # 动态的加属性
    class Person():
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
    p = Person('nick', 19)
    key=input('请输入key: ')
    value=input('输入value: ')
    setattr(p,key,value)
    print(p.age)
    print(p.__dict__)
    
    '''
    请输入key:nick
    输入value:123
    19
    {'name': 'nick', 'age': 19, 'nick': '123'}
    '''
    
    # 动态的删属性
    p.name = 'lqz'
    p.age = 18
    p.sex = 'male'
    a = input('请输入要删除的属性: ')
    print(p.__dict__)
    delattr(p, a)
    print(p.__dict__)
    """
    请输入要删除的属性: sex
    {'name': 'lqz', 'age': 18, 'sex': 'male'}
    {'name': 'lqz', 'age': 18}
    """
    
    # 动态的加方法
    # 需要先写一个函数,然后通过setattr()往对象中加方法
    
    def test(a):
        print(a)
    
    print(p.__dict__)
    setattr(p, 'test', test)
    print(p.__dict__)
    p.test(0) # 0
    
    #模块也是对象,也可以用这四个方法
    
    #内置模块
    import os
    print(hasattr(os, 'path1')) #False
    
    
    #使用自己写的模块,通过反射来获取模块中是否有我要使用的属性或方法,如果有就执行,没有就报错
    
    #这种方法可以用在:我想调用别人写的模块,但是我并不知道他写没写完,所以我需要用到hasattr先判断是否存在,存在的话用getattr拿到它,否则抛异常
    '''
    #别人写的,领导规定要写speak,run,eat方法
    #这个人没写完
    #utils.py
    
    def speak():
        print('speak')
    
    
    def run():
        print('run')
    #这个人写完了
    #def eat():
        print('eat')
        
    #opera.py
    import utils
    
    if hasattr(utils, 'eat')
    	eat = getattr(utils, 'eat')
    	eat()
    else:
    	print('那个人还没写完呢')
    
    # 那个人还没写完呢
    '''
    
    
    

    内置方法

    __str__

    
    class Foo:
        def __init__(self, name):
            self.name = name
        def __str__(self):
            return '['+self.name+']'
    
    f = Foo('nick')
    print(f) #print会按照__str__里面重写的格式进行打印
    # print(f.__str__()) # 打印结果同上:  [nick]
    
    l = [1, 2, 3]
    print(l) # [1, 2, 3]本质也是调用list的__str__方法
    
    

    点拦截方法

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

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

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

    class Foo:
        def __init__(self, name):
            self.name = name # name没拿到值,要进入到__setarr__中,
            #  找到后打印出来name的值 'nick'
            print(name)
        def __getattr__(self, item):
            return '没有这个字段'
        def __setattr__(self, key, value):# key值是参数name,
            # value是值'nick'
            print(key)
            print(value)
        def __delattr__(self, item):
            print('zzzz')
    
    f = Foo('nick') # 生成对象调用__init__方法,
    print(f.name) #重写了__setattr__, 所以找不到name,这样就会进入__getattr__中
    
    
    
    #######
    #小例子#
    #######
    
    # 写一个类继承字典, 让他可以.取值,也可以中括号取值
    class Mydict(dict):
        def __init__(self, **kwargs):
            super().__init__(**kwargs)
        def __getattr__(self, item):
            # pass
            return self[item]
    
    di = Mydict(name = 'lqz', age = 18)
    print(di['age'])
    print(di.name) #点取值找不到,
    # 会触发__getattr__,继承了字典,直接利用key返回value
    
    

    []中括号拦截

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

    #实现机理和.拦截一样,只不过是对象
    # 用中括号调用时会触发
    class Foo:
        def __init__(self, name):
            self.name = name
        def __getitem__(self, item):
            name = getattr(self, item) # 通过反射
            # 拿到nick,并返回,这句话之后可
            # 以使用中括号进行取值
            return name
        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')
    f['name'] = 'ljy'
    del f['name']
    # print(f.name)
    print(f['name'])
    

    ()对象加小括号拦截

    _call_

    class Foo:
        def __call__(self):
            print('xxxx')
    f = Foo()
    f()
    
    # xxxx
    
  • 相关阅读:
    PostgreSQL 数据类型
    Oracle存储过程
    网络安全统计显示XSS和过时的软件是主要问题
    XSS Fuzzer工具
    Windows安全擦除硬盘擦除器
    msfvenom生成payload命令+内网透到外网
    owaspbwa筆記
    laraval框架model注意事项
    windows mysql utf-8中文乱码解决方法
    为laravel分页样式制定class
  • 原文地址:https://www.cnblogs.com/michealjy/p/11454082.html
Copyright © 2011-2022 走看看