转载自
https://www.jianshu.com/nb/27681479?native.theme=1
面向对象
另外,这里self就是指类本身,self.name就是Student类的属性变量,是Student类所有。而name是外部传来的参数,不是Student类所自带的。故,self.name = name的意思就是把外部传来的参数name的值赋值给Student类自己的属性变量self.name。
// An highlighted block
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
def print_score(self):
print("%s: %s" % (self.name, self.score))
3.假设已经有鸟类的定义,现在我要定义企鹅类继承于鸟类,但我们都知道企鹅是不会飞的,我们应该如何屏蔽父类(鸟类)中飞的方法?
答:覆盖父类方法,例如将函数体内容写pass,这样调用fly方法就没用任何反应了。
class Bird:
def fly(self):
print("Fly away!")
class Penguin(Bird):
def fly(self):
pass
bird = Bird()
penguin = Penguin()
bird.fly()
penguin.fly() # 不输出
只输出一个Fly away!
在多重继承中,使用super().init()来替代father.init(self)
eg
class B(A):
def __init__(self):
super().__init__()
to replace
class B(A):
def __init__(self):
A.__init__(self)
#老办法
class D(B, C):
def __init__(self):
print("进入D...")
B.__init__(self)
C.__init__(self)
print("离开D...")
#较优
class D(B, C):
def __init__(self):
print("进入D...")
super().__init__()
print("离开D...")
Line 中没有继承Point,但是p1是Point,Line中用到了P1,所以Line其实还是继承了Point
import math
class Point():
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def getX(self):
return self.x
def getY(self):
return self.y
class Line():
def __init__(self, p1, p2):
self.x = p1.getX() - p2.getX()
self.y = p1.getY() - p2.getY()
self.len = math.sqrt(self.x * self.x + self.y * self.y)
def getLen(self):
return self.len
p1 = Point(1, 1)
p2 = Point(1, 4)
line = Line(p1, p2)
print(line.getLen())
注意组合后self.turtule.num
# 乌龟类
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.fish = Fish(y) # 把鱼类实例化组合进来
def print_num(self):
print("水池里总共有乌龟 %d 只,小鱼 %d 条!" % (self.turtle.num, self.fish.num))
pool = Pool(1, 10)
pool.print_num()
class Stack():
def __init__(self, start=[]):
self.stack = []
for x in start:
self.push(x)
def isEmpty(self): # 判断是否为空
return not self.stack
def push(self, obj): # 入栈
print("成功入栈数据:", obj)
self.stack.append(obj)
def pop(self): # 出栈
if not self.stack:
print("警告:栈为空!")
else:
print("成功出栈数据:", self.stack[-1])
return self.stack.pop()
def top(self): # 显示第一个栈顶数据
if not self.stack:
print("警告:栈为空!")
else:
print("栈顶数据为:", end="")
return self.stack[-1]
def bottom(self): # 显示栈底数据
if not self.stack:
print("警告:栈为空!")
else:
print("栈底数据为:", end="")
return self.stack[0]
def showStack(self): # 展示栈内的所有数据(自己附加上去的方法,为了方便看栈内还有哪些数据)
print("目前栈内的所有数据为:", end="")
return self.stack[:]
s = Stack([])
print(s.isEmpty()) # True
s.push('1')
s.push('2')
s.push('3')
s.push('4')
s.push('5')
print(s.showStack())
print(s.top()) # 栈顶是5
s.pop() # 5被弹出,栈顶变成4
print(s.showStack())
print(s.top())
print(s.bottom())
>>> class C:
def __init__(self, x=0):
self.x = x
>>> c1 = C()
>>> hasattr(c1, 'x')
True
>>> hasattr(c1, 'y')
False
property(fget=None, fset=None, fdel=None, doc=None)
用来通过属性来设置属性。
property()函数中的三个函数分别对应的是获取属性的方法、设置属性的方法以及删除属性的方法,这样一来,外部的对象就可以通过访问x的方式,来达到获取、设置或删除属性的目的。
当需要更改上例中的getSize、setSize或delSize函数的名称时,如果这些方法是作为接口让用户调用的,那么对用户而言就要修改自己调用的方法名,很麻烦,使用了proprty()后,用户就不需担心这种问题了。
class Timer:
def init():
self.start =
def start()
Timer.start
class C2F(float):
"摄氏度转换为华氏度"
def __new__(cls, arg=0.0):
return float.__new__(cls, arg * 1.8 + 32)
```
# super 魔法方法进阶
```java
class A(object):
def __init__(self, a=0):
self.a = a
def get(self):
return self.a
class B(A):
def __init__(self, b):
super().__init__(b)
def get(self):
return super().get()
if __name__ == '__main__':
b = B(10)
print(b.get())
```
# timer
```java
#!/usr/bin/python
# -*- coding:utf-8 -*-
import time as t
class MyTimer:
def __init__(self):
self.unit = ['年', '月', '天', '小时', '分钟', '秒']
self.prompt = "未开始计时!"
self.lasted = []
self.begin = 0
self.end = 0
# 开始计时
def start(self):
self.begin = t.localtime()
self.prompt = "提示:请先调用stop()结束计时!"
print("计时开始……")
# 停止计时
def stop(self):
if not self.begin:
print("提示:请先调用start()开始计时!")
else:
self.end = t.localtime()
self._calc()
print("计时结束!")
# 内部方法,计算运行时间
def _calc(self):
self.lasted = []
self.prompt = "总共运行了"
for index in range(6):
self.lasted.append(self.end[index] - self.begin[index])
if self.lasted[index]:
self.prompt += (str(self.lasted[index]) + self.unit[index])
# 为下一轮计算初始化变量
self.begin = 0
self.end = 0
print(self.prompt)
# 调用实例直接显示结果
def __str__(self):
return self.prompt
__repr__ = __str__
# 计算两次计时器对象之和
def __add__(self, other):
prompt = "总共运行了"
result = []
for index in range(6):
result.append(self.lasted[index] + other.lasted[index])
if result[index]:
prompt += (str(result[index]) + self.unit[index])
return prompt
t1 = MyTimer()
t2 = MyTimer()
t1.start()
t.sleep(45)
t1.stop()
t2.start()
t.sleep(15)
t2.stop()
print(t1 + t2)
魔法方法 含义
__ getattr__(self, name) 定义当用户试图获取一个不存在的属性时的行为
__ getattribute__(self, name) 定义当该类的属性被访问时的行为
__ setattr__(self, name, value) 定义当一个属性被设置时的行为
__ delattr__(self, value) 定义当一个属性被删除时的行为
>>> class MyDescriptor:
# self是描述符自身的实例;instance是这个描述符的拥有着所在类的实例,在这里也就是Test类的实例;owner是这个描述符的拥有者所在的类本身
def __get__(self, instance, owner):
print("getting...", self, instance, owner)
# 参数value是等号右边的值,就是下面的'X-man'
def __set__(self, instance, value):
print("setting...", self, instance, value)
def __delete__(self, instance):
print("delete...", self, instance)
>>> class Test:
x = MyDescriptor()
>>> test = Test()
>>> test.x
getting... <__main__.MyDescriptor object at 0x000001A2EA6D86D8> <__main__.Test object at 0x000001A2EA668278> <class '__main__.Test'>
>>> test
<__main__.Test object at 0x000001A2EA668278>
>>> Test
<class '__main__.Test'>
>>> test.x = 'X-man'
setting... <__main__.MyDescriptor object at 0x000001A2EA6D86D8> <__main__.Test object at 0x000001A2EA668278> X-man
>>> del test.x
delete... <__main__.MyDescriptor object at 0x000001A2EA6D86D8> <__main__.Test object at 0x000001A2EA668278>