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
- 上下文管理器.