称为构造方法,用于构造该类的对象,python通过调用构造方法返回该类的对象(无须使用new),用于初始化python对象
语法格式:
类名[field1=值1, field2=值2,…]
代码如下:
class Apple:
# 实现构造器
def __init__(self, color, weight):
self.color = color;
self.weight = weight;
# 重写__repr__方法,用于实现Apple对象的“自我描述”
def __repr__(self):
return "Apple[color=" + self.color +\
", weight=" + str(self.weight) + "]"
a = Apple("红色" , 5.68)
# 打印Apple对象
print(a)
与_init_()方法对应的是_del_()方法,_ init _ () 方法用于初始化Python对象,而_del_()
则用于销毁Python对象一在任何Python对象将要被系统回收之时,系统都会自动调用该对象的_del_()方法。
对象的_dir_()方法用于列出该对象内部的所有属性(包括方法)名,该方法将会返回包含所有属性(方法)名的序列。
_dict_属性用于査看对象内部存储的所有属性名和属性值组成的字典,通常程序直接使用该属性即可。程序使用_dict_属性既可查看对象的所有内部状态,也可通过字典语法来访问或修改指定属性的值。例如如下程序。
代码如下:
class Item:
def __init__ (self, name, price):
self.name = name
self.price = price
im = Item('鼠标', 28.9)
print(im.__dict__) # ①
# 通过__dict__访问name属性
print(im.__dict__['name'])
# 通过__dict__访问price属性
print(im.__dict__['price'])
im.__dict__['name'] = '键盘'
im.__dict__['price'] = 32.8
print(im.name) # 键盘
print(im.price) # 32.8
当程序操作(包括访问、设置、删除)对象的属性时,Python系统同样会执行该对象特定的方法。
这些方法共涉及如下几个:
_ getattribute _(self, name):当程序访问对象的name属性时被自动调用。
_ getattr _(self, name):当程序访问对象的name属性且该属性不存在时被自动调用。
_ setattr _(self, name, value):当程序对对象的name属性赋值时被自动调用。
_ delattr _(self, name):当程序删除对象的name属性时被自动调用。
代码如下:
class Rectangle:
def __init__ (self, width, height):
self.width = width
self.height = height
def __setattr__(self, name, value):
print('----设置%s属性----' % name)
if name == 'size':
self.width, self.height = value
else:
self.__dict__[name] = value
def __getattr__(self, name):
print('----读取%s属性----' % name)
if name == 'size':
return self.width, self.height
else:
raise AttributeError
def __delattr__(self, name):
print('----删除%s属性----' % name)
if name == 'size':
self.__dict__['width'] = 0
self.__dict__['height'] = 0
rect = Rectangle(3, 4)
print(rect.size)
rect.size = 6, 8
print(rect.width)
del rect.size
print(rect.size)
>> ----设置width属性----
>> ----设置height属性----
>> ----读取size属性----
>> (3, 4)
>> ----设置size属性----
>> ----设置width属性----
>> ----设置height属性----
>> 6
>> ----删除size属性----
>> ----读取size属性----
>> (0, 0)
如果程序需要在读取、设置属性之前进行某种拦截处理(比如检査数据是否合法之类的),也可通过重写_setattr_ ()或_getattribute_方法来实现。
代码如下:
class User:
def __init__ (self, name, age):
self.name = name
self.age = age
# 重写__setattr__()方法对设置的属性值进行检查
def __setattr__ (self, name, value):
# 如果正在设置name属性
if name == 'name':
if 2 < len(value) <= 8:
self.__dict__['name'] = value
else:
raise ValueError('name的长度必须在2~8之间')
elif name == 'age':
if 10 < value < 60:
self.__dict__['age'] = value
else:
raise ValueError('age值必须在10~60之间')
u = User('fkit', 24)
print(u.name)
print(u.age)
#u.name = 'fk' # 引发异常
u.age = 2 # 引发异常
在动态检査对象是否包含某些属性(包括方法)相关的函数有如下几个。
判断:hasattr(obj, name):检査/判断obj对象是否包含名为name的属性或方法。
获取:getattr(object, name[, default]):获取object对象中名为name的属性的属性值。
改变/添加:setattr(obj, name, value, /):将 obj 对象的 name 属性设为 value,改变/添加python对象的属性照顾。
代码如下:
class Comment:
def __init__ (self, detail, view_times):
self.detail = detail
self.view_times = view_times
def info ():
print("一条简单的评论,内容是%s" % self.detail)
c = Comment('疯狂Python讲义很不错', 20)
# 判断是否包含指定的属性或方法
print(hasattr(c, 'detail')) # True
print(hasattr(c, 'view_times')) # True
print(hasattr(c, 'info')) # True
# 获取指定属性的属性值
print(getattr(c, 'detail')) # '疯狂Python讲义很不错'
print(getattr(c, 'view_times')) # 20
# 由于info是方法,故下面代码会提示:name 'info' is not defined
#print(getattr(c, info, '默认值'))
# 为指定属性设置属性值
setattr(c, 'detail', '天气不错')
setattr(c, 'view_times', 32)
# 输出重新设置后的属性值
print(c.detail)
print(c.view_times)
# 设置不存在的属性,即为对象添加属性
setattr(c, 'test', '新增的测试属性')
print(c.test) # 新增的测试属性
def bar ():
print('一个简单的bar方法')
# 将c的info方法设为bar函数
setattr(c, 'info', bar)
c.info() # 方法调用方法,info()方法调用bar()函数
# 将c的info设置为字符串'fkit'
setattr(c, 'info', 'fkit')
c.info() # 方法设置为字符串,报错TypeError
程序可用hasattr()函数判断指定属性(或方法)是否存在,但到底是属性还是方法,则需要进一步判断它是否可调用。程序可通过判断该属性(或方法)是否包含_call_属性来确定它是否可调用。
代码如下:
class User:
def __init__(self, name, passwd):
self.name = name
self.passwd = passwd
def validLogin (self):
print('验证%s的登录' % self.name)
u = User('crazyit', 'leegang')
# 判断u.name是否包含__call__方法,即判断是否可调用
print(hasattr(u.name, '__call__')) # False
# 判断u.passwd是否包含__call__方法,即判断是否可调用
print(hasattr(u.passwd, '__call__')) # False
# 判断u.validLogin是否包含__call__方法,即判断是否可调用
print(hasattr(u.validLogin, '__call__')) # True
# 定义Role类
class Role:
def __init__ (self, name):
self.name = name
# 定义__call__方法
def __call__(self):
print('执行Role对象')
r = Role('管理员')
# 直接调用Role对象,就是调用该对象的__call__方法
r() # r() = r__call__()
def foo ():
print('--foo函数--')
# 下面示范了2种方式调用foo()函数,效果完全相同
foo()
foo.__call__()
代码如下:
def check_key (key):
'''
该函数将会负责检查序列的索引,该索引必须是整数值,否则引发TypeError
且程序要求索引必须为非负整数,否则引发IndexError
'''
if not isinstance(key, int): raise TypeError('索引值必须是整数')
if key < 0: raise IndexError('索引值必须是非负整数')
if key >= 26 ** 3: raise IndexError('索引值不能超过%d' % 26 ** 3)
class StringSeq:
def __init__(self):
# 用于存储被修改的数据
self.__changed = {}
# 用于存储已删除元素的索引
self.__deleted = []
def __len__(self):
return 26 ** 3
def __getitem__(self, key):
'''
根据索引获取序列中元素
'''
check_key(key)
# 如果在self.__changed中找到已经修改后的数据
if key in self.__changed :
return self.__changed[key]
# 如果key在self.__deleted中,说明该元素已被删除
if key in self.__deleted :
return None
# 否则根据计算规则返回序列元素
three = key // (26 * 26)
two = ( key - three * 26 * 26) // 26
one = key % 26
return chr(65 + three) + chr(65 + two) + chr(65 + one)
def __setitem__(self, key, value):
'''
根据索引修改序列中元素
'''
check_key(key)
# 将修改的元素以key-value对的形式保存在__changed中
self.__changed[key] = value
def __delitem__(self, key):
'''
根据索引删除序列中元素
'''
check_key(key)
# 如果__deleted列表中没有包含被删除key,添加被删除的key
if key not in self.__deleted : self.__deleted.append(key)
# 如果__changed中包含被删除key,删除它
if key in self.__changed : del self.__changed[key]
# 创建序列
sq = StringSeq()
# 获取序列的长度,实际上就是返回__len__()方法的返回值
print(len(sq))
print(sq[26*26])
# 打印没修改之后的sq[1]
print(sq[1]) # 'AAB'
# 修改sq[1]元素
sq[1] = 'fkit'
# 打印修改之后的sq[1]
print(sq[1]) # 'fkit'
# 删除sq[1]
del sq[1]
print(sq[1]) # None
# 再次对sq[1]赋值
sq[1] = 'crazyit'
print(sq[1]) # crazyit
需要实现迭代器,只要实现如下两个方法即可。
_ iter _(self):该方法返回一个迭代器(iterator),迭代器必须包含一个 _ next _()方法,该方法返回迭代器的下一个元素。
_ reversed _(self):该方法主要为内建的reversed()反转函数提供支持,当程序调用reversed()函数对指定迭代器执行反转时,实际上是由该方法实现的。
代码如下:
class Fibs:
def __init__(self, len):
self.first = 0
self.sec = 1
self.__len = len
# 定义迭代器所需的__next__方法
def __next__(self):
# 如果__len__属性为0,结束迭代
if self.__len == 0:
raise StopIteration
# 完成数列计算:
self.first, self.sec = self.sec, self.first + self.sec
# 数列长度减1
self.__len -= 1
return self.first
# 定义__iter__方法,该方法返回迭代器
def __iter__(self):
return self
# 创建Fibs对象
fibs = Fibs(10)
# 获取迭代器的下一个元素
print(next(fibs))
# 使用for-in循环遍历迭代器
for el in fibs:
print(el, end=' ')
# 将列表转换为迭代器
my_iter = iter([2, 'fkit', 4])
# 依次获取迭代器的下一个元素
print(my_iter.__next__()) # 2
print(my_iter.__next__()) # fkit
如果程序明确需要一个特殊的列表、元组或字典类,我们有两种选择。
代码如下:
# 定义ValueDict类,继承dict类
class ValueDict(dict):
# 定义构造函数
def __init__(self, *args, **kwargs):
# 调用父类的构造函数
super().__init__(*args, **kwargs)
# 新增getkeys方法
def getkeys(self, val):
result = []
for key, value in self.items():
if value == val: result.append(key)
return result
my_dict = ValueDict(语文 = 92, 数学 = 89, 英语 = 92)
# 获取92对应的所有key
print(my_dict.getkeys(92)) # ['语文', '英语']
my_dict['编程'] = 92
print(my_dict.getkeys(92)) # ['语文', '英语', '编程']
生成器和迭代器的功能非常相似,它也会提供_next_()方法,这意味着程序同样可调用内置的next。函数来获取生成器的下一个值,也可使用fbr循环来遍历生成器。
生成器与迭代器的区别在于:迭代器通常是先定义一个迭代器类,然后通过创建实例来创建迭代器;而生成器则是先定义一个包含yield语句的函数,然后通过调用该函数来创建生成器。
创建生成器需要两步操作。
①定义一个包含yield语句的函数。
②调用第①步创建的函数得到生成器。
差值递增数列
def test(val, step):
print("--------函数开始执行------")
cur = 0
# 遍历0~val
for i in range(val):
# cur添加i*step
cur += i * step
yield cur
# print(cur, end=' ')
# 执行函数,返回生成器
t = test(10, 2)
print('=================')
# 获取生成器的第一个值
print(next(t)) # 0,生成器“冻结”在yield处
print(next(t)) # 2,生成器再次“冻结”在yield处
for ele in t:
print(ele, end=' ')
# 再次创建生成器
t = test(10, 1)
# 将生成器转换成列表
print(list(t))
# 再次创建生成器
t = test(10, 3)
# 将生成器转换成列表
print(tuple(t))
>> =================
>> --------函数开始执行------
>> 0
>> 2
>> 6 12 20 30 42 56 72 90 --------函数开始执行------
>> [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]
>> --------函数开始执行------
>> (0, 3, 9, 18, 30, 45, 63, 84, 108, 135)
yield cur语句的作用有两点。
在程序被yield语句冻结之后,当程序再次调用next()函数获取生成器的下一个值时,程序才会继续向下执行。
需要指出的是,调用包含yield语句的函数并不会立即执行,它只是返回一个生成器。只有当程序通过next。函数调用生成器或遍历生成器时,函数才会真正执行。
Python主要提供了以下两种方式来创建生成器。
生成器是Python的一个特色功能,在其他语言中往往没有对应的机制,因此很多Python开发者对生成器机制不甚了解。但实际上生成器是一种非常优秀的机制,以我们实际开发的经验来看,使用生成器至少有以下几个优势。
外部程序通过send。方法发送数据。
生成器函数使用yield语句接收收据。
代码如下:
def square_gen(val):
i = 0
out_val = None
while True:
# 使用yield语句生成值,使用out_val接收send()方法发送的参数值
out_val = (yield out_val ** 2) if out_val is not None else (yield i ** 2)
# 如果程序使用send()方法获取下一个值,out_val会获取send()方法的参数
if out_val is not None : print("====%d" % out_val)
i += 1
sg = square_gen(5)
# 第一次调用send()方法获取值,只能传入None作为参数
print(sg.send(None)) # 0
print(next(sg)) # 1
print('--------------')
# 调用send()方法获取生成器的下一个值,参数9会被发送给生成器
print(sg.send(9)) # 81
# 再次调用next()函数获取生成器的下一个值
print(next(sg)) # 9
# 让生成器引发异常
#sg.throw(ValueError)
# 关闭生成器
sg.close()
print(next(sg)) # StopIteration
生成器还提供了如下两个常用方法。
object._ add_(self, other):加法运算,为“+“运算符提供支持。
object._ sub_(self, other):减法运算,为“-”运算符提供支持。
object._ mul_(self, other):乘法运算,为“*“运算符提供支持。
object._ matmul_(self, other):矩阵乘法,为”@”运算符提供支持。
object._ truediv_(self, other):除法运算,为“/”运算符提供支持。
object._ floordiv_(self, other):整除运算,为“//”运算符提供支持。
object._ mod_(self, other):求余运算,为“%”运算符提供支持。
object._ divmod_(self, other):求余运算,为divmod运算符提供支持。
object._ pow_(self, other[, modulo]):乘方运算,为”** ”运算符提供支持。
object._ lshift_(self, other):左移运算,为“<<”运算符提供支持。
object._ rshift_(self, other):右移运算,为“>>”运算符提供支持。
object._ and_(self, other):按位与运算,为“&”运算符提供支持。
object._ xor_(self, other):按位异或运算,为"^“运算符提供支持。
object._ or_(self, other):按位或运算,为”|"运算符提供支持。
代码如下:
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
# 定义setSize()函数
def setSize (self , size):
self.width, self.height = size
# 定义getSize()函数
def getSize (self):
return self.width, self.height
# 使用property定义属性
size = property(getSize, setSize)
# 定义__add__方法,该对象可执行+运算
def __add__(self, other):
# 要求参与+运算的另一个运算数必须是Rectangle
if not isinstance(other, Rectangle):
raise TypeError('+运算要求目标是Rectangle')
return Rectangle(self.width + other.width, self.height + other.height)
def __repr__(self):
return 'Rectangle(width=%g, height=%g)' % (self.width, self.height)
r1 = Rectangle(4, 5)
r2 = Rectangle(3, 4)
# 对两个Rectangle执行加法运算
r = r1 + r2
print(r) # Rectangle(width=7, height=9)
当程序执行x + y运算时,Python首先会尝试使用X的_add_方法进行计算;如果x没有提
供_3£1<1_方法,Python还会尝试调用y M_radd_^法进行计算。这意味着上面介绍的各种数值运算相关方法,还有一个带r的版本。
object._ radd_(self other):当 y 提供该方法时,可执行 x + y。
object._ rsub_(self, other):当 y 提供该方法时,可执行 x - y。
object._ rmul_(self, other):当 y 提供该方法时,可执行 x * y。
object._ rmatmul_(self, other):当 y 提供该方法时,可执行 x @ y。
object._ rtruediv_(self, other):当 y 提供该方法时,可执行 x / y。
object._ rfloordiv_(self, other):当 y 提供该方法时,可执行 x // y。
object._ rmod_(self, other):当 y 提供该方法时,可执行 x % y。
object._ rdivmod_(self, other):当 y 提供该方法时,可执行 x divmod y。
object._ rpow_(self, other):当 y 提供该方法时,可执行 x ** y。
object._ rlshift_(self, other):当 y 提供该方法时,可执行 x << y。
object._ rrshift_(self, other):当 y 提供该方法时,可执行 x >> y。
object._ rand_(self, other):当 y 提供该方法时,可执行 x & y。
object._ rxor_(self, other):当 y 提供该方法时,可执行 x ^y。
object._ ror_(self, other):当y提供该方法时,可执行x | y。
简单来说,如果自定义类提供了上面列出的_rxxx_()方法,那么该自定义类的对象就可以出现在对应运算符的右边。
代码如下:
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
# 定义setSize()函数
def setSize (self , size):
self.width, self.height = size
# 定义getSize()函数
def getSize (self):
return self.width, self.height
# 使用property定义属性
size = property(getSize, setSize)
# 定义__radd__方法,该对象可出现在+的右边
def __radd__(self, other):
# 要求参与+运算的另一个运算数必须是数值
if not (isinstance(other, int) or isinstance(other, float)):
raise TypeError('+运算要求目标是数值')
return Rectangle(self.width + other, self.height + other)
def __repr__(self):
return 'Rectangle(width=%g, height=%g)' % (self.width, self.height)
r1 = Rectangle(4, 5)
# r1有__radd__方法,因此它可以出现在+运算符的右边
r = 3 + r1
print(r) # Rectangle(width=7, height=8)
Python还支持各种扩展后的賦值运算符,这些扩展后的赋值运算符也是由特殊方法来
提供支持的。
object._ iadd_(self, other):为"+=“运算符提供支持。
object._ isub_(self, other):为”-=“运算符提供支持。
object._ imul_(self, other):为 “*=”运算符提供支持。
object._ imatmul_(self, other):为“@=” 运算符提供支持。
object._ itruediv_(self, other):为“/=”运算符提供支持。
object._ ifloordiv_(self, other):为”//=”运算符提供支持。
object._ imod_(self, other):为 “%=”运算符提供支持。
object._ ipow_(self, other[, modulo]):为 “**= ” 运算符提供支持。
object._ ilshift_(self, other):为 “<<=“运算符提供支持。
object._ irshift_(self, other):为”>>=” 运算符提供支持。
object._ iand_(self, other):为“&=“运算符提供支持。
object._ ixor_(self, other):为”^=“运算符提供支持。
object._ ior_(self, other):为”|="运算符提供支持。
代码如下:
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
# 定义setSize()函数
def setSize (self , size):
self.width, self.height = size
# 定义getSize()函数
def getSize (self):
return self.width, self.height
# 使用property定义属性
size = property(getSize, setSize)
# 定义__iadd__方法,该对象可支持+=运算
def __iadd__(self, other):
# 要求参与+=运算的另一个运算数必须是数值
if not (isinstance(other, int) or isinstance(other, float)):
raise TypeError('+=运算要求目标是数值')
return Rectangle(self.width + other, self.height + other)
def __repr__(self):
return 'Rectangle(width=%g, height=%g)' % (self.width, self.height)
r = Rectangle(4, 5)
# r有__iadd__方法,因此它支持+=运算
r += 2
print(r) # Rectangle(width=6, height=7)
object._ It_(selfi other):为“<”运算符提供支持。
object._ le_(sel£ other):为“<=”运算符提供支持。
object._ eq_(sel£ other):为“==”运算符提供支持。
object._ ne_(selC other):为“!=”运算符提供支持。
object._ gt_(self, other):为“>”运算符提供支持。
object._ ge_(sel£ other):为“>="运算符提供支持。
代码如下:
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
# 定义setSize()函数
def setSize (self , size):
self.width, self.height = size
# 定义getSize()函数
def getSize (self):
return self.width, self.height
# 使用property定义属性
size = property(getSize, setSize)
# 定义__gt__方法,该对象可支持>和<比较
def __gt__(self, other):
# 要求参与>运算的另一个运算数必须是Rectangle
if not isinstance(other, Rectangle):
raise TypeError('>运算要求目标是Rectangle')
return True if self.width * self.height > other.width * other.height else False
# 定义__eq__方法,该对象可支持==和!=比较
def __eq__(self, other):
# 要求参与==运算的另一个运算数必须是Rectangle
if not isinstance(other, Rectangle):
raise TypeError('==运算要求目标是Rectangle')
return True if self.width * self.height == other.width * other.height else False
# 定义__ge__方法,该对象可支持>=和<=比较
def __ge__(self, other):
# 要求参与>=运算的另一个运算数必须是Rectangle
if not isinstance(other, Rectangle):
raise TypeError('>=运算要求目标是Rectangle')
return True if self.width * self.height >= other.width * other.height else False
def __repr__(self):
return 'Rectangle(width=%g, height=%g)' % (self.width, self.height)
r1 = Rectangle(4, 5)
r2 = Rectangle(3, 4)
print(r1 > r2) # True
print(r1 >= r2) # True
print(r1 < r2) # False
print(r1 <= r2) # False
print(r1 == r2) # False
print(r1 != r2) # True
print('------------------')
r3 = Rectangle(2, 6)
print(r2 >= r3) # True
print(r2 > r3) # False
print(r2 <= r3) # True
print(r2 < r3) # False
print(r2 == r3) # True
print(r2 != r3) # False
Python还提供了 + (单目求正)、-(单目求负)、~ (单目取反)等运算符;这些运算符也有对应的特殊方法。
object._ neg_(self):为单目求负(-)运算符提供支持。
object._ pos_(self):为单目求正(+)运算符提供支持。
object._ invert_(self):为单目取反(〜)运算符提供支持。
代码如下:
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
# 定义setSize()函数
def setSize (self , size):
self.width, self.height = size
# 定义getSize()函数
def getSize (self):
return self.width, self.height
# 使用property定义属性
size = property(getSize, setSize)
# 定义__neg__方法,该对象可执行求负(-)运算
def __neg__(self):
self.width, self.height = self.height, self.width
def __repr__(self):
return 'Rectangle(width=%g, height=%g)' % (self.width, self.height)
r = Rectangle(4, 5)
# 对Rectangle执行求负运算
-r
print(r) # Rectangle(width=5, height=4)
Python提供了 str()、int()、float。、complex。等函数(其实是这些类的构造器)将其他类型的对象转换成字符串、整数、浮点数和复数,这些转换同样也是由特殊方法在底层提供支持的。下面是这些特殊方法。
object._ str_(self):对应于调用内置的strQ函数将该对象转换成字符串。
object._ bytes_(self):对应于调用内置的bytes。函数将该对象转换成字节内容。该方法应
该返回bytes对象。
object._ complex_(self):对应于调用内置的complex()函数将该对象转换成复数。该方法
应该返回complex对象。
object._ int_(self):对应于调用内置的int()函数将对象转换成整数。该方法应该返回int
对象。
object._ float_(self):对应于调用内置的float。函数将对象转换成浮点数。该方法应该返回
float对象。
代码如下:
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
# 定义setSize()函数
def setSize (self , size):
self.width, self.height = size
# 定义getSize()函数
def getSize (self):
return self.width, self.height
# 使用property定义属性
size = property(getSize, setSize)
# 定义__int__方法,程序可调用int()函数将该对象转成整数
def __int__(self):
return int(self.width * self.height)
def __repr__(self):
return 'Rectangle(width=%g, height=%g)' % (self.width, self.height)
r = Rectangle(4, 5)
print(int(r)) # 20
Python还提供了一些常见的内建函数,当使用这些内建的函数处理对象时,实际上也是由以下特殊方法来提供支持的。
object._ format_(self, format spec):对应于调用内置的format()函数将对象转换成格式化字符串。
object._ hash_(self):对应于调用内置的hash。函数来获取该对象的hash码。
object._ abs_(self):对应于调用内置的abs()函数返回绝对值。
object._ round_(self[, ndigits]):对应于调用内置的round。函数执行四舍五入取整。
object._ trunc_(self):对应于调用内置的trunc()函数执行截断取整。
object._ floor_(self):对应于调用内置的floor()函数执行向下取整。
object_ ceil_(self):对应于调用内置的ceil()函数执行向上取整。
代码如下:
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
# 定义setSize()函数
def setSize (self , size):
self.width, self.height = size
# 定义getSize()函数
def getSize (self):
return self.width, self.height
# 使用property定义属性
size = property(getSize, setSize)
# 定义__round__方法,程序可调用round()函数将该对象执行四舍五入取整
def __round__(self, ndigits=0):
self.width, self.height = round(self.width, ndigits), round(self.height, ndigits)
return self
def __repr__(self):
return 'Rectangle(width=%g, height=%g)' % (self.width, self.height)
r = Rectangle(4.13, 5.56)
# 对Rectangle对象执行四舍五入取整
result = round(r, 1)
print(r) # Rectangle(width=4.1, height=5.6)
print(result) # Rectangle(width=4.1, height=5.6)