魔法方法
- 魔法方法
- 一.构造和析构
- 二.算术运算
- 三.简单定制
- 四.属性访问
- 五.描述符
- 异常处理
- 1.异常情况
- 2.处理异常
- 练习题
魔法方法
一.构造和析构
1.init(self[,…])
只有在需要进行初始化的时候才重写__init__()方法。同时__init__()方法的返回值一定是None.
class Rectangle:
def __init__(self,x,y):
self.x=x
self.y=y
def getPeri(self):
return (self.x + self.y)*2
def getArea(self):
return self.x*self.y
2.new(cls[,…])
class CapStr(str):
def __new__(cls,string):
string = string.upper()
return str.__new__(cls,string)
a=CapStr("I love FishC.com")
print(a)
3.del(self)
class C:
def __init__(self):
print("我是__init__方法,我被调用了")
def __del__(self):
print("我是__del__方法,我被调用了")
二.算术运算
1.常见的算术运算
class New_int(int):
def __add__(self,other):
return int.__sub__(self,other)
def __sub__(self,other):
return int.__add__(self,other)
a=New_int(3)
b=New_int(4)
print(a+b)
-1
print(a-b)
7
2.反运算
反运算相关的魔法方法与算术运算相关的魔法方法保持一一对应的关系,不同之处就是反运算的魔法方法多了一个" r ",例如,add()就对应__radd__().
反运算中如果a对象的__add__()方法没有实现或者不支持相应的操作,那么Python就会自动调用b的__radd__()方法。
class Nint(int):
def __radd__(self,other):
return int.__sub__(other,self)
a = Nint(5)
b = Nint(8)
print(a+b)
13
print(1+b)
-7
3.Python支持的一元操作符
neg()表示正号行为;
pos()表示负号行为;
abs()表示定义abs()函数(取绝对值)被调用的行为;
invert()表示定义按位取反的行为。
三.简单定制
基本要求:
定制一个计时器的类;
start和stop方法代表启动计时和结束计时;
假设计时器对象t1,print(t1)和直接调用t1均显示结果;
当计时器未启动或已经停止计时,调用stop方法会给予温馨的提示;
两个计时器对象可以相加:t1+t2;
只能使用提供的有限资源完成。
案例如下:
import time as t
class MyTimer:
def __init__(self):
self.unit = ["年","月","日","小时","分钟","秒"]
self.prompt="未开始计时"
self.lasted = []
self.begin = 0
self.end = 0
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
#开始计时
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
四.属性访问
1.通常可以通过点(.)操作符的形式去访问对象的属性。
class C:
def __init__(self):
self.x="X-man"
c=C()
c.x
"X-man"
2.property()函数使得我们可以用属性去访问属性
class C:
def __init__(self,size=10):
self.size=size
def getSize(self):
return self.size
def setSize(self,value):
self.size=value
def delSize(self):
del self.size
x=property(getSize,setSize,delSize)
3.特殊属性__dict__
__dict__的作用是以字典的形式显示出当前对象的所有属性以及相对应的值。
class Rectangle:
def __init__(self,width=0,height=0):
self.width=width
self.height=height
def __setattr__(self,name,value):
if name =="square":
self.width=value
self.height=value
else:
self.__dict__[name]=value
def getArea(self):
return self.width*self.height
五.描述符
get(self,instance,owner):用于访问属性,返回属性的值
set(self,instance,value):将在属性分配操作中调用,不返回任何内容
delete(self,instance):控制删除操作,不返回任何内容
class MyProperty:
def __init__(self,fget=None,fset=None,fdel=None):
self.fget=fget
self.fset=fset
self.fdel=fdel
def __get__(self,instance,owner):
return self.fget(instance)
def __set__(self,instance,value):
self.fset(instance,value)
def __delete__(self,instance):
self.fdel(instance)
class C:
def __init__(self):
self._x=None
def getX(self):
return self._x
def setX(self,value):
self._x=value
def delX(self):
del self._x
x=MyProperty(getX,setX,delX)
#先执行上述代码
c=C()
c.x="X-man"
c.x
"X-man"
c._x
"X-man"
异常处理
1.异常情况
#AssertionError:断言语句失败
my_list=["小甲鱼"]
assert len(my_list)>0
print(my_list.pop())
assert len(my_list)>0
#AttributeError:尝试访问未知的对象属性
my_list=[]
my_list.fishc
#IndexError:索引超出序列的范围
my_list=[1,2,3]
my_list[3]
#KeyError:字典中查找一个不存在的关键字
my_dict={"one":1,"two":2,"three":3}
print(my_dict["one"])
print(my_dict["four"])
#NameError:尝试访问一个不存在的变量
print(fishc)
#SyntaxError:Python的语法错误
print"I love fishc.com"
#TypeError:不同类型间的无效操作
1+"1"
#ZeroDivisionError:除数为0
5/0
2.处理异常
(1)except后面跟着多个异常,对这些异常进行统一处理
try:
int("abc")
sum = 1+"1"
f=open("我为什么不是一个文件.txt")
print(f.read())
f.close()
except (ValueError,TypeError,OSError)as reason:
print("出错\n错误原因是:"+str(reason))
(2)finally语句块中的内容就是确保无论如何都将被执行的内容
try:
f=open("我是一个不存在的文档.txt","w")
print(f.write("我困了"))
sum = 1+"1"
except(TypeError,OSError):
print("出错了")
finally:
f.close
(3)else语句
try:
int("123")
except ValueError as reason:
print("出错了"+str(reason))
else:
print("没有任何异常")
(4)with语句
try:
with open("data.txt","w")as f:
for each_line in f:
print(each_line)
except OSError as reason:
print("出错"+str(reason))
练习题
1.定义一个类实现银行帐户的概念,包括的变量有“帐号”和“存款余额” ,包括的方法有“存款”、“取款”和“查询余额”。定义类,创建帐户类的对象,并完成相应操作。
class BankNums:
def __init__(self, ID, money):
self.ID = ID
self.money = money
def addMoney(self, money):
self.money += money
print(f"存入金额:{money}元,余额{self.money}")
def quMoney(self, money):
self.money -= money
print(f"取出金额:{money}元,余额{self.money}")
def lookMoney(self):
print(f"余额 %s" % self.money)
user = BankNums(ID=1, money=10)
user.addMoney(90)
user.quMoney(70)
user.lookMoney()
2.定义了一个学生的类 Student,包括成员属性“学号”、“班号”、“姓名”、“性别”、“年龄”,成员方法:“获得学号”、“获得班号”、“获得性别”、“获得姓名”、“获得年龄”。写一个构造方法将所有属性初始化,增加一个方法toString()把 Student类对象的所有信息组合成一个字符串。 添加equals方法:仅当学号相等时,认为两个学生相等。
class Student():
def __init__(self,name,sec,num1,num2,age):
self.name =name
self.sec=sec
self.num1=num1
self.num2=num2
self.age=age
def getA(self):
return self.name
def getB(self):
return self.sex
def getC(self):
return self.num1
def getD(self):
return self.num2
def getE(self):
return self.age
def toString(self):
return self.name,self.sec,self.num1,self.num2,self.age
def equals(self,other):
return self.num1==other.num1
a=Student("小红","女",21,2,18)
b=Student("小芳","女",21,6,18)
print(a.equals(b))
print(a.toString())
3.定义Point、Circle、Cylinder(点、圆、圆柱) 三个类,三个类都拥有 x,y 属性,而 Circle 又增加了属性radius,Cylinder 类又增加了属性 height。都有获得 x,y 坐标,设置 x,y 坐标,求圆的面积、圆柱的体积的方法。
import math
class Point():
def __init__(self,x,y):
self.x=x
self.y=y
def getXY(self):
return self.x,self.y
class Circle(Point):
def __init__(self,x,y,r):
super().__init__(x,y)
self.r=r
def s(self):
return math.pi*self.r**2
class Cylinder(Circle):
def __init__(self,x,y,r,h):
super().__init__(x,y,r)
self.h=h
def v(self):
return math.pi*self.r**2*self.h
if __name__=="__main__":
a = Cylinder(2,2,1,5)
print(a.getXY())
print(a.s())
print(a.v())