zoukankan      html  css  js  c++  java
  • issubclass和isinstance 反射 内置方法(魔术方法)

    issubclass 和 isinstance

    issubclass

    判断一个类是不是另一个类子类

    class Foo:
        pass
    
    
    class Bar:
        pass
    
    
    class T(Foo, Bar):
        pass
    
    
    print(issubclass(T, Bar))
    

    isinstance

    判断第一个是不是第二个的参数生成的对象

    class Foo:
        pass
    
    
    class Bar:
        pass
    
    
    a = Foo()
    print(isinstance(a, Foo))
    print(isinstance(a, Bar))
    

    反射

    1.用户输入一段字符串,执行该字符串对应的方法
    hasattr():判断字符串在对象里面是否有,返回值是布尔类型
    getatter():把字符串对应的属性或者方法拿出来
    setatter():向对象中添加一个和字符串一样名字的方法或者属性
    delatter():通过字符串来删除属性或方法

    class Foo:
    def run(self):
    print("run......")

    def speak(self):
        print("speak......")
    
    p = Foo()
    # 方案一:
    print(Foo.__dict__['run'](p))
    # 方案二:
    cmd = input("请输入功能:")
    if hasattr(p, cmd):
        getattr(p, cmd)
    else:
        print("没有这个功能")
    

    通过用户输入的key,value往对象中赋值

    key = input("key:")
    value = input("value:")
    setattr(Foo, key, value)
    print(p.age)
    

    动态的往对象中放方法

     def eat():
         print('eat...')
         # return eat()
     setattr(p,'eat222',eat)
     s = p.eat222
     s()
     print(s)
    

    动态的删除属性

    # 原始的删除方法
     p.name = 'xc'
     print(p.__dict__)
     del p.name
     print(p.__dict__)
    

    动态删除对象中的属性

     choice = input("请输入需要删除的功能:")
     p.name = 'xc'
     p.age = 18
     print(p.__dict__)
     delattr(p, choice)
     print(p.__dict__)
    

    删除对象中属性名为name字符串的属性

     class Foo:
         def __init__(self, name, age):
             self.name = name
             self.age = age
    
         def run(self):
             print("run...")
    
    
     p = Foo('xc', 123)
     cmd = 'name'
     if hasattr(p, cmd):
         print("存在")
         print(p.__dict__)
         delattr(p, cmd)
         print(p.__dict__)
     else:
         print("不存在")
    

    反射:通过=字符串=来获取,设置,删除对象中的属性或方法

    写的时候想起之前的内容

     class A:
         pass
     class B(A):
         pass
     class X(B):
         def __init__(self, name, age):
             self.name = name
             self.age = age
    
         def run(self):
             print("run...")
    
     p = X('xc', 12)
     print(p.__dict__) # 打印类中所有的属性
     print(X.__bases__) # 只打印父类
     print(X.mro()) # 打印所有的父类,即分类以上的,并且查找顺序严格按照mro的顺序来
    

    例子(还是上面的四个方法,hasattr(),setattr(),getattr(),delattr())

    class BlackMedium:
        feature = "ugly"
    
        def __init__(self, name, addr):
            self.name = name
            self.addr = addr
        
        def sell_house(self):
            print("最怕中介买房子,自己还是傻逼")
        
        def rent_house(self):
            print("最怕中介租房子,自己还是傻逼")
    
    
    b1 = BlackMedium('东方明珠', '上海')
    print(b1.__dict__)
    
    a = 'sell_house'
    getattr(b1, a)()
    
    # 删除属性或者方法
    delattr(b1, 'name')
    print(b1.__dict__)
    
    # 模块也是对象,也可以使用四个方法
    import os
    
    print(hasattr(os, 'path1'))  # False
    
    • 使用自己写的模块,通过反射来获取模块中是否有我要使用的属性或方法,若果有就执行,没有就报错

    • 类似于 hasattr(模块名/文件名,变量名/方法名-->要使用字符串形式)

    • 内置方法(就是重写一些方法,更改返回值)

      • init :格式化属性
      • str :给类添加返回值,也就是可以使用print打印类,返回的不再是内存地址
      • repr :和str类似,不过是在交互式命令下直接写变量名,会执行__repr__

    点拦截方法, setattr,delattr,getattr

    • 如果去对象中取属性,一旦取不到,会进入到__getattr__
    • 如果删除对象中的属性,就会进入__delattr__
    • 如果去给对象中的属性赋值,就会进入到__setattr__
    • 并且都不会改变原有的值,就是不执行原来的语句,转来执行自身定义的里面的代码
     class Foo:
         def __init__(self, name):
             self.name = name
         def __getattr__(self, item):
             return 1
         def __delattr__(self, item):
             return 2
         def __setattr__(self, key, value):
             print(3)
             return 3
     p = Foo('xc')
     p.name = 100
     print(p.name)
     del p.name
     print(p.xc)
    

    原来的字典使用方式

    • dict
    di = dict(name='xc', age=18)
    
    # 正常方式
    
    print(di['name'])
    
    
    # 我们需要实现的方式
    
    di.name --> 这样肯定是报错的
    di.age = 10
    
    class Mydict(dict):
        def __init__(self, **kwargs):
            super().__init__(**kwargs)
    
        def __setattr__(self, key, value):
            self[key] = value
        
        def __getattr__(self, item):
            return self[item]
    
    
    di = Mydict(a=123, b=3456)
    print(di["a"])
    print(di.a)
    

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

    call 对象加括号会调用它

    enter 和 __exit 我们所使用的就是 with open

    • 上下文管理器.
  • 相关阅读:
    WPF数据爬取小工具-某宝推广位批量生成,及订单爬取 记:接单最痛一次的感悟
    .net core2.1
    Ng Alain使用
    MediatR
    RN错误随笔
    【转载】DDD分层架构的三种模式
    1.RN环境搭建,创建项目,使用夜神模拟调试
    ExtJs4 笔记(2) ExtJs对js基本语法扩展支持
    ExtJs4 笔记(1) ExtJs大比拼JQuery:Dom文档操作
    vue的父子通信
  • 原文地址:https://www.cnblogs.com/xiongchao0823/p/11448938.html
Copyright © 2011-2022 走看看