目录:
- isinstance和issubclass
- 反射
- getattr
- hasattr
- setattr
- delattr
- __str__和__repr__
- __del__
- item系列:
- __getitem__
- __delitem__
- __setitem__
- __new__(单例设计模式)
- __call__
- __len__
- __hash__
- __eq__
isinstance和issubclass
isinstance(obj, cls):返回True和False 判断obj是否属于cls这个类。
class A:
a = 'dddd'
def __init__(self, name, age):
self.name = name
self.age = age
class B(A):
pass
a = B('我是a', 'none')
print(isinstance(a, B))
print(isinstance(a, A))
输出结果:
True
True
可以看到子类实例化的对象也是属于父类的
issubclass(sub, super)检查sub类是否是 super 类的派生类
class Foo(object):
pass
class Bar(Foo):
pass
issubclass(Bar, Foo)
输出结果为:
True
object是所有类的父类
反射
python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
四个可以实现自省的函数
class A:
a = 'dddd'
def __init__(self, name, age):
self.name = name
self.age = age
def tell(self):
print('telling')
'判断是否有该属性'
print(hasattr(A, 'tell'))
a = A('我是a', 'none')
'拿到属性'
t = getattr(a, 'tell')
'设置属性'
setattr(a, 'sex', '男')
'删除属性'
delattr(a, 'sex')
我们可以将hasattr和getattr一起使用:
class A:pass
com = input('请输入指令:')
if hasattr(A, com):
ret = getattr(A, com)
ret()
可以用作判断使用。
本模块的导入
import sys
def s1():
print('s1')
def s2():
print('s2')
hasattr(sys.modules[__name__], s1)
getattr(sys.modules[__name__], s2)
__str__和__repr__
format_str = {
'net':'{obj.name} - {obj.age}',
'ten':'{obj.name} * {obj.age}',
'nte':'{obj.name} + {obj.age}'
}
class A:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return self.name
def __str__(self):
return self.name
def __format__(self, format_spec):
if not format_spec or format_spec not in format_str:
format_spec = 'net'
fmt = format_str[format_spec]
return fmt.format(obj=self)
a = A('stay', 20)
print('%r'%a)
print('%s'%a)
print(format(a, 'net'))
__del__
析构方法,当对象在内存中被释放时,自动触发执行。
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
class Foo:
def __del__(self):
print('执行我啦')
f1=Foo()
del f1
print('------->')
#输出结果
执行我啦
------->
先执行__del__方法再删除
item系列
class A:
def __init__(self,name):
self.name = name
def __getitem__(self, item):
return self.__dict__[item]
def __setitem__(self, key, value):
self.__dict__[key] = value
def __delitem__(self, key): # 只有对对象像字典一样操作时才会条用item系列方法
print('删除obj[key]执行') # ******
self.__dict__.pop(key)
def __delattr__(self, item): #对对象用对象.的方式进行调用时会调用
print('删除obj.key执行') # *****
self.__dict__.pop(item)
a = A('我是A')
a['age'] = 11
a['sex'] = '男'
print(a.age)
print(a['sex'])
del a.age
del a['sex']
__new__
单例设计模式:
class A:
def __new__(cls, *args, **kwargs):
if not hasattr(cls, '_instance'):
cls._instance = object.__new__(cls)
return cls._instance
a = A()
b = A()
print(id(a), id(b))
__call__
对象后面加括号,触发执行。
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 call 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
class Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print('__call__')
obj = Foo() # 执行 __init__
obj() # 执行 __call__
__len__
class A:
def __init__(self):
self.a = 1
self.b = 2
def __len__(self):
return len(self.__dict__)
a = A()
print(len(a))
__hash__
class A:
def __init__(self):
self.a = 1
self.b = 2
def __hash__(self):
return hash(str(self.a)+str(self.b))
a = A()
print(hash(a)
__eq__
class A:
def __init__(self):
self.a = 1
self.b = 2
def __eq__(self,obj):
if self.a == obj.a and self.b == obj.b:
return True
a = A()
b = A()
print(a == b)
一个比较牛逼的例子
class Person:
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def __hash__(self):
return hash(self.name+self.sex)
def __eq__(self, other):
if self.name == other.name and self.sex == other.sex:return True
p_lst = []
for i in range(84):
p_lst.append(Person('egon',i,'male'))
print(p_lst)
print(set(p_lst))
感觉这重写的方式和java的差不多都是重写hash和eq