一、常用魔方方法
(一)__del__()方法--销毁魔术方法
当一个对象在内存中被销毁的时候自动执行,至少有一个self参数,接收对象。
程序自动调用此方法,不需要我们手动调用。
class A():
num=0 # 类属性,也叫静态属性
def __init__(self,name):
A.num+=1 # 每定义一个对象,计数器加1
self.name=name
def __del__(self):
A.num-=1
print(self.name,'被删除,还剩下{}个对象'.format(A.num))
a=A('张三')
b=A('李四')
c=A('王五')
print(A.num)
del a # 自动调用__del__()
del b
del c
(二)__call__()方法
可以让类的实例具有类似于函数的行为,进一步模糊了函数和对象之间的概念。
对象后面加括号,就像函数一样触发执行。形如:对象名()或类名()()。
class A():
def __init__(self,num):
self.num=num
def __call__(self,n):
return self.num*n
a=A(7)
print(a(9))
print(A(3)(7))
斐波那契序列
class Fib():
def __init__(self):
pass
def __call__(self,month):
lst=[]
a,b=1,1
n=1
while n<=month:
lst.append(a)
a,b=b,a+b
n+=1
return lst
f=Fib()
for i in range(1,10):
print(f(i))
class Fib():
def __init__(self):
pass
def __call__(self,month):
a,b=0,1
n=1
while n<=month:
a,b=b,a+b
n+=1
return a
f=Fib()
m=int(input('请输入:'))
print(f(m))
(三)__str__()方法和__repr__()方法--改变对象的字符串显示
__repr__()是__str_()方法的备胎,找不到__str__()就会找它。
%s和str()默认调用__str__()。
%r和repr()默认调用__repr__()。
class Per():
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return '%s:%d'%(self.name,self.age)
def __repr__(self):
return '我叫{},年龄{}'.format(self.name,self.age)
a=Per('张三',19)
print(a)
print(str(a))
print('%s'% a)
print('%r'% a)
print(repr(a))
(四)__new__()方法--实例化魔方方法
在实例化对象是自动触发。
至少有一个cls参数,接收当前类,返回一个对象实例。
先触发__new__()才会触发__init__()。
class Stu():
# 实例化
def __new__(cls, *args, **kwargs):
print('111111111111111111111')
# 如果不写这句,就没有创建对象,只打印111,不打印222。调用父类的__nuw__()方法就可以创建对象了。
return object.__new__(cls)
# 初始化
def __init__(self,name,age):
print('222222222222222222222')
self.name=name
self.age=age
zs=Stu('张三',19)
print(zs.name)
(五)is和==的区别
is比较两个对象的id值是否相等,是否指向同一个内存地址。
==比较的是两个对象的内容是否相同,默认调用对象的__eq__()方法。
继承自object的__eq__()方法比较两个对象的id。但对于自定义的对象,一般认为对象的值相同就是同一个对象,因此需要复写__eq__()方法。
class Stu():
def __init__(self,name,age):
self.name=name
self.age=age
def __eq__(self, other): # equal
return self.__dict__==other.__dict__
a=Stu('张三',19)
b=Stu('张三',19)
c=Stu('李四',20)
print(a==b) # True
print(a is b) # False
# !!!重点
d=[]
d.append(a)
if b not in d: # 去调用了__eq__(),发现a==b,所以列表中只有一个对象。说明这里的in是根据==判断的。
d.append(b)
print(d)
(六)__hash__()方法--哈希/散列
将一个不定长的输入,通过哈希函数变换成一个定长的输出,即哈希值。
这种哈希变换是一种单向运算,具有不可逆性即不能根据哈希值还原出输入的信息。
set集合要求数据是可哈希的,因为set集合会默认调用对象的__hash__()函数进行快速查询,如果找到了则调用对象的__eq__()函数判断两个是否相同,如果相同则不添加。
在自定义类中,如果没有实现__eq__()和__hash__(),会继承object的__eq__()和__hash__()。如果只定义__eq__()方法,没有定义__hash__(),__hash__()方法会隐式设置为None。
hash()函数默认调用object类的__hash__()方法,Hash值是对象的id值的十六分之一。
class Stu():
def __init__(self,name):
self.name=name
a=Stu('张三')
b=Stu('李四')
c=Stu('王五')
s={a,b,c}
print(s)
print(hash(a))
print(id(a)/16)
结果:
{<__main__.Stu object at 0x0000000002877C50>, <__main__.Stu object at 0x0000000001E498D0>, <__main__.Stu object at 0x000000000286D0F0>}
1984909
1984909.0
class Stu():
def __init__(self,name):
self.name=name
def __eq__(self, other):
print('222')
return self.name==other.name
def __hash__(self):
print('111')
return hash(self.name)
a=Stu('张三')
b=Stu('李四')
c=Stu('张三')
print(id(a))
print(id(b))
print(id(c))
print(a==c)
d={a,b,c}
print(d)
结果:
42630336
42630224
42683696
222
True
111
111
111
222
{<__main__.Stu object at 0x00000000028A7CC0>, <__main__.Stu object at 0x00000000028A7C50>}
二、类的常用函数
(一)issubclass()--检测一个类,是否为另一个类的子类
格式:issubclass(被检测类,父类)。若一次判断多个父类,有一则为真。
class A():
pass
class B(A):
pass
print(issubclass(B,A))
(二)isinstance()--检测一个对象是否为某个类的对象
格式:isinstance(对象,类)。若一次判断多个类,有一则为真。
class A():
pass
a=A()
print(isinstance(a,A))
(三)反射函数
1.hasattr()--判断是否有此变量,返回值为bool类型
2.getattr()--获取属性值或者获取方法变量的地址,返回值为数值
3.delattr()--删除类或者对象的属性或方法
4.setattr()--给类或者对象设置属性或者方法
class A():
dog=0
def hehe(num):
print(num)
setattr(A,'dog',90)
print(A.__dict__)
setattr(A,'cat',10)
print(A.__dict__)
a=A()
print(a.__dict__)
setattr(a,'haha',1999)
print(a.__dict__)
a.hehe=2022
print(a.__dict__)
print(getattr(A,'dog'))
f=getattr(A,'hehe')
f(1)
delattr(A,'dog')
print(hasattr(A,'dog'))
class A():
def f1(self):
print('我是f1')
def f2(self):
print('我是f2')
def f3(self):
print('我是f3')
print(A.__dict__)
a=A()
while True:
f=input('请输入你想调用的方法:')
if hasattr(A,f):
fc=A.__dict__.get(f)
fc(a)
else:
print('A类没有',f)
5.反射导入的模块中的属性、函数、类
t1模块:
d='周2'
def func(a):
print('你好是函数',a)
class A():
def __init__(self,name):
self.name=name
t2:
import t1
x=getattr(t1,'d')
print(x)
f=getattr(t1,'func')
f('张三')
cls=getattr(t1,'A')
a=cls('张三')
print(a.name)
6.反射自己模块中的属性和函数
import sys
zhutou=299
def func():
print('aaaaaaaaaaaaaaaaa')
# 查看所有模块
print(sys.modules)
# 反射当前模块
print(sys.modules['__main__'])
# 反射当前模块中的zhutou变量
x=getattr(sys.modules['__main__'],'zhutou')
print(x)
x=getattr(sys.modules['__main__'],'func')
x()
7.反射内置模块
import time
print(time.time())
t=getattr(time,'time')
print(t())