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

  • 上下文管理器.
posted @ 2019-09-02 20:52  cheerxiong  阅读(220)  评论(0编辑  收藏  举报