类与对象
练习题
1、以下类定义中哪些是类属性,哪些是实例属性?
class Test(object):
class_attr = 100 # 类属性
def __init__(self):
self.sl_attr = 100 # 实例属性
def func(self):
print('类对象.类属性的值:', Test.class_attr) # 调用类属性
print('self.类属性的值', self.class_attr) # 相当于把类属性 变成实例属性
print('self.实例属性的值', self.sl_attr) # 调用实例属性
2、怎么定义私有⽅法?
python中并不存在完全意义上的私有,根据约定就_xx定义为私有,可以被外部直接访问,而__叫做伪私有,外部访问麻烦一些
3、尝试执行以下代码,并解释错误原因:
class C:
def myFun():
print('Hello!')
c = C()
c.myFun()
# 报错原因:myFun()少了个self,而且把c=C()和c.myFun()写进了类中
# 纠正
class C:
def myFun(self):
print('Hello!')
c = C()
c.myFun()
Hello!
4、按照以下要求定义一个游乐园门票的类,并尝试计算2个成人+1个小孩平日票价。
要求:
- 平日票价100元
- 周末票价为平日的120%
- 儿童票半价
class Ticket():
def __init__(self, man, child, week):
if not isinstance(man, int) and not isinstance(child, int):
raise TypeError('type must be int')
if man < 0 and child < 0 and week not in ['weekday', 'weekend']:
raise ValueError('value wrong')
self._man_num = man
self._child_num = child
self._week = week
def get_price(self):
if self._week == 'weekday':
return 100 * self._man_num + 50 * self._child_num
else:
return 120 * self._man_num + 60 * self._child_num
ticket = Ticket(2, 1, 'weekday')
ticket.get_price()
250
魔法方法
练习题
1、上面提到了许多魔法方法,如__new__
,__init__
, __str__
,__repr__
,__getitem__
,__setitem__
等等,请总结它们各自的使用方法。
__new__
:
__new__
是在一个对象实例化的时候所调用的第一个方法,在调用__init__
初始化前,先调用__new__
。__new__
至少要有一个参数cls
,代表要实例化的类,此参数在实例化时由 Python 解释器自动提供,后面的参数直接传递给__init__
。__new__
对当前类进行了实例化,并将实例返回,传给__init__
的self
。但是,执行了__new__
,并不一定会进入__init__
,只有__new__
返回了,当前类cls
的实例,当前类的__init__
才会进入。- 若
__new__
没有正确返回当前类cls
的实例,那__init__
是不会被调用的,即使是父类的实例也不行,将没有__init__
被调用。- 可利用
__new__
实现单例模式。__new__
方法主要是当你继承一些不可变的 class 时(比如int, str, tuple
)
__init__
:
- 构造器,当一个实例被创建的时候调用的初始化方法
__str__
:
- 当你打印一个对象的时候,触发
__str__
- 当你使用
%s
格式化的时候,触发__str__
str
强转数据类型的时候,触发__str__
__rstr__
:
repr
是str
的备胎- 有
__str__
的时候执行__str__
,没有实现__str__
的时候,执行__repr__
repr(obj)
内置函数对应的结果是__repr__
的返回值- 当你使用
%r
格式化的时候 触发__repr__
__getitem__
:
__getitem__(self, key)
定义获取容器中元素的行为,相当于self[key]
。
__setitem__
:
__setitem__(self, key, value)
定义设置容器中指定元素的行为,相当于self[key] = value
。
2、利用python做一个简单的定时器类
要求:
- 定制一个计时器的类。
start
和stop
方法代表启动计时和停止计时。- 假设计时器对象
t1
,print(t1)
和直接调用t1
均显示结果。 - 当计时器未启动或已经停止计时时,调用
stop
方法会给予温馨的提示。 - 两个计时器对象可以进行相加:
t1+t2
。 - 只能使用提供的有限资源完成。
import time
class Timer:
def __init__(self):
self._time = False
def start(self):
self._start = time.time()
self._time = True
print('计时开始!')
def end(self):
if self._time == False:
print('计时器未启动或已经停止计时')
return
else:
self._end = time.time()
self._time = False
print('计时结束!')
def __str__(self):
return '计时为 %.2f 秒' % (self._end - self._start)
# 直接调用
def __repr__(self):
return '计时为 %.2f 秒' % (self._end - self._start)
def __add__(self, other):
self._result = self._end - self._start
other._result = other._end - other._start
return print('计时的和为 %.2f 秒' % (self._result + other._result))