039
组合
形参实参结合
class Turtle:
def __init__(self,x):
self.num=x
class fish:
def __init__(self,x):
self.num=x
class Pool:
def __init__(self,x,y):
self.turtle=Turtle(x)#形参实参必须要结合,括号里不能没有东西
self.fishing=fish(y)
def printnum(self):
print('水池中共有乌龟 %d只,小鱼 %d 条'%(self.turtle.num,self.fishing.num))
a=Pool(1,10)
a.printnum()
水池中共有乌龟 1只,小鱼 10 条
python严格要求方法需要有实例才能被调用,这种限制其实就是python所谓的绑定概念
修改已经实例化的对象不会影响类,但是修改类会影响以后再去实例化的对象,已经造出来的没影响
创建的实例对象是被pytho的垃圾回收机制回收的
040
类和对象相关命令
- 亲子鉴定函数
class A:
pass
class B(A):
pass
print(issubclass(B,A))
print(issubclass(B,B))#亲子鉴定函数
class C:
pass
print(issubclass(B,C))
True
True
False
- 判断实例化的对象是否属于该类的函数
isinstance()
class A:
pass
class B(A):
pass
class C:
pass
b1=B()
print(isinstance(b1,B))
print(isinstance(b1,A))
print(isinstance(b1,C))
print(isinstance(b1,(A,C)))#也支持元祖
True
True
False
True
- has attribute测试属性
hasattr(object,name),后面的name一定要用’ ’ 引起来,不然会报错,检查这个对象是否有这个属性
class A:
def __init__(self,x=0):
self.x=x
c1=A()
print(hasattr(c1,'x'))
print(hasattr(c1,x))
Traceback (most recent call last):
File "D:/pycharm222/001.py", line 7, in <module>
print(hasattr(c1,x))
NameError: name 'x' is not defined
True
- getattr(object,name,default),取出来那个属性的值
class A:
def __init__(self,x=0):
self.x=x
c1=A()
print(getattr(c1,'x'))
print(getattr(c1,'y','您所访问的属性不存在'))
0
您所访问的属性不存在
- setattr(object,name,value)给对象创造一个新的属性
class A:
def __init__(self,x=0):
self.x=x
c1=A()
print(getattr(c1,'x'))
print(getattr(c1,'y','您所访问的属性不存在'))
setattr(c1,'y','hello')
print(getattr(c1,'y','您所访问的属性不存在'))
0
您所访问的属性不存在
hello
- delattr(object,name)删除属性
加上default也可以捕获异常
041
面向对象的方法
- def init(self):构造函数
class A:
def __init__(self,x,y):
self.x=x
self.y=y
def getp(self):
return (self.x+self.y)*2
def getarea(self):
return self.x *self.y
rect=A(3,4)
print(rect.getp())
print(rect.getarea())
14
12
- 在创建继承时,如果父类不能够改变,需要使用__new__来解决,即类函数的重写和覆盖
class cap(str):
def __new__(cls, string):
string=string.upper()
return str.__new__(cls,string)
a=cap('hello world')
print(a)
HELLO WORLD
- 析构函数_def_(self)
class C:
def __init__(self):#构造
print('我是init方法,我被调用了')
def __del__(self):#析构函数
print('我是del方法,我被调用了')
c1=C()
c2=c1
c3=c2
del c3
我是init方法,我被调用了
我是del方法,我被调用了
042
自己重新定义减法,类似运算符重载??__ add__
class new(int):
def __add__(self, other):
return int.__sub__(self,other)
def __sub__(self, other):
return int.__add__(self,other)
a=new(3)
b=new(5)
print(a+b)
print(int.__sub__(5,9))
print(5-9)
下面是__radd__(self, other):的使用,a=5,5+2正常执行为7,7+b不能执行,所以启用radd
class nint(int):
def __radd__(self, other):
return int.__sub__(self,other)
a=nint(5)
b=nint(6)
print(a+b)
print(1+b)#启用radd
11
5
044
#repr()方法是__str__()方法的备胎。如果有__str__()方法,那么print(’%s) str(obj)都先去执行__str__()方法,并且使用__str__()方法的返回值
#如果没有__str__()方法,那么print(’%s’) str(oj)都会执行__repr__()方法
计时器不想看了
045
访问属性
class C:
def __init__(self):
self.x='x-man'
c=C()
print(getattr(c,'x'))
print(getattr(c,'y','没有这个属性'))
x-man
没有这个属性
046
描述符
__ get__(self,instance,owner)
class mydes:
def __get__(self, instance, owner):
print('getting...',self,instance,owner)
def __set__(self, instance, value):
print('setting...',self,instance,value)
def __delete__(self, instance):
print('deleting',self,instance)
class Test:
x=mydes()
ts=Test()
ts.x
ts.x = 'yes'
del ts.x
getting... <__main__.mydes object at 0x0000023E1BA8F630> <__main__.Test object at 0x0000023E1BA8F6D8> <class '__main__.Test'>
setting... <__main__.mydes object at 0x0000023E1BA8F630> <__main__.Test object at 0x0000023E1BA8F6D8> yes
deleting <__main__.mydes object at 0x0000023E1BA8F630> <__main__.Test object at 0x0000023E1BA8F6D8>
下面是利用描述符将摄氏度转化为华氏度,instance指的是实例化的对象,赋值时调set函数,输出时调用get函数。
作用:把对函数的调用表现成对属性的操作
class C:
def __init__(self,value=26.0):
self.value=float(value)
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
self.value=float(value)
class F:
def __get__(self, instance, owner):
return instance.cel*1.8+32
def __set__(self, instance, value):
instance.cel=(float(value)-32)/1.8#会去修改cel中的属性,会调用set函数吗
class T:
cel=C()
fah=F()
temp=T()#应该是调用init
print(temp.cel)#调用get
print(temp.fah)#调用get
temp.cel=30
print(temp.fah)
temp.fah=100
print(temp.cel)
26.0
78.80000000000001
86.0
37.77777777777778
047
容器类型
len(self) 定义当被 len() 调用时的行为(返回容器中元素的个数)
len(self) | 定义当被 len() 调用时的行为(返回容器中元素的个数) |
---|---|
getitem(self, key) | 定义获取容器中指定元素的行为,相当于 self[key] |
setitem(self, key, value) | 定义设置容器中指定元素的行为,相当于 self[key] = value |
delitem(self, key) | 定义删除容器中指定元素的行为,相当于 del self[key] |
iter(self) | 定义当迭代容器中的元素的行为 |
reversed(self) | 定义当被 reversed() 调用时的行为 |
contains(self, item) | 定义当使用成员测试运算符(in 或 not in)时的行为 |
048
迭代 iter() 得到迭代器
next()
string='fishs'
it=iter(string)
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))
Traceback (most recent call last):
File "D:/pycharm222/001.py", line 9, in <module>
print(next(it))
StopIteration
f
i
s
h
s
Process finished with exit code 1
下面使用while来配合迭代器
string='fishs'
it=iter(string)
while True:
try:
each=next(it)
except StopIteration:
break
print(each)
f
i
s
h
s
fib数列的迭代
class F:
def __init__(self):
self.a=0;
self.b=1;
def __iter__(self):
return self
def __next__(self):
self.a,self.b=self.b,self.a+self.b
return self.a
fib=F()
for each in fib:
if each <20:
print(each)
else:
break
中间的self.a,self.b=self.b,self.a+self.b可以替换成
def next(self):
t = self.b
self.b = self.a + self.b
self.a = t
return self.a
1
1
2
3
5
8
13
另一种,可以对项的大小进行限制,比如项中最大的数为60
class F:
def __init__(self,n=60):
self.a=0
self.b=1
self.n=n
def __iter__(self):
return self
def __next__(self):
self.a,self.b=self.b,self.a+self.b
if self.a >self.n:
raise StopIteration
return self.a
fib=F()
for each in fib:
print(each)
1
1
2
3
5
8
13
21
34
55
Process finished with exit code 0
049
生成器yield,调用可以暂停或挂起
相同点:功能都是返回程序执行结果
区别:yield返回执行结果并不中断程序执行,return在返回执行结果的同时中断程序执行。
def mygen():
print('生成器被执行')
yield 1
yield 2
m=mygen()
print(next(m))
print(next(m))
#print(next(m))
for i in mygen():
print(i)
生成器被执行
1
2
生成器被执行
1
2
下面利用生成器来解决fib数列,有点类似return
def lib():
a=0
b=1
while True:
a,b=b,a+b#和之前上面那个函数一个样
yield a
for each in lib():
if each > 100:
break
print(each)
1
1
2
3
5
8
13
21
34
55
89
yield用法:当你调用这个函数的时候,你写在这个函数中的代码并没有真正的运行
1.不用迭代的
>>> mylist = [x*x for x in range(3)]
>>> for i in mylist:
... print(i)
0
1
4
2.使用yield的迭代后
>>> def createGenerator():
... mylist = range(3)
... for i in mylist:
... yield i*i
...
>>> mygenerator = createGenerator() # create a generator
>>> print(mygenerator) # mygenerator is an object!
<generator object createGenerator at 0xb7555c34>
>>> for i in mygenerator:
... print(i)
0
1
4