一、类的定制
1、时间模块:time模块,用local time获取时间
- 时间戳(timestamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。返回的是flot类型。产生时间戳方式的函数主要有time(),clock()等。
- 格式化的时间字符串(Format String)
- 结构化的时间(struct_time):struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)。返回struct_time的方法有gmtime(),localtime(),strptime()
localtime()返回的是一个元组,元组中有九个元素,我们只需要用到前面六个,分别是年月日时分秒,所以用检索元组的形式,分别定位,再做差,再将差值用字符串拼接的方式得到一个持续的时间。
class MyTimer():
# 开始计时
def start(self):
self.start = t.localtime()
print('计时开始...')
# 停止计时
def stop(self):
self.stop = t.localtime()
self._calc()
print('计时结束...')
def _calc(self):
self.lasted = []
self.prompt = '总共运行了'
for index in range(6):
self.lasted.append(self.stop[index] - self.start[index])
self.prompt += str(self.lasted[index])
print(self.prompt)
运行:
>>> t1 = MyTimer()
>>> t1.start()
计时开始...
>>> t1.stop()
总共运行了000007
计时结束...
>>>
2、魔法方法__str__ 、__repr__
,被打印的时候需要字符串的形式输出时,直接打印A()
class A():
def __str__(self):
return '今天是个好天气'
class B():
def __repr__(self):
return '今天天气真好!'
运行:
>>> b = B()
>>> print(b)
今天天气真好!
>>> a = A()
>>> print(a)
今天是个好天气
>>>
import time as t
class MyTimer():
def __init__(self):
self.begin = 0
self.end = 0
self.prompt = '未开始计时'
self.lasted = []
self.unit = ['年','月','天','小时','分钟','秒']
def __str__(self):
return self.prompt
__repr__ = __str__
# 开始计时
def start(self):
self.begin = t.localtime()
print('计时开始...')
# 停止计时
def stop(self):
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]
print(self.prompt)
==================== RESTART: C:\Users\1\Desktop\练习\11.py ====================
>>> t1 = MyTimer()
>>> t1.start()
计时开始...
>>> t1.stop()
总共运行了6秒
计时结束...
>>>
二、属性访问(属性是特征,方法是功能)
1、属性的具体:一篇很好的文章:
https://www.cnblogs.com/gouguoqilinux/p/9194093.html
1、__getattr__(self,name)
定义当用户试图获取一个不存在的属性时的行为
class Demo:
def __getattr__(self,name):
return "该属性不存在!" #改写了getattr的方法,窥见getattr的用法
运行:
>>> demo = Demo()
>>> demo.x
'该属性不存在!'
2、__getattribute__(self,name)
,定义当该类的属性被访问时的行为
运行会先调用getattribute,当属性不存在时转而再调用getattr,若是赋值操作,则直接调用setattr
3、__setattr__(self,name)
,定义当一个属性被设置时的行为
4、__delattr__(self,name)
,定义当一个属性被删除时的行为
class Demo():
def __getattr__(self,name):
self.name ='i love here'
return self.name
def __setattr__(self,name,value):
super().__setattr__(name,value)
return self.name
>>> demo =Demo()
>>> demo.x
'i love here'
>>> demo.x = 'ASD'
>>> demo.x
'ASD'
>>>
方法二:
class Demo:
def __getattr__(self,name):
self.name = 'Iam here'
return self.name
5、练习:
写一个类,定义一个矩形,具有长和宽两个属性,返回面积。如果为一个叫square的属性赋值,默认长和宽等于该边长
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 :
super().__setattr__(name,value) #如果直接定义self.name = value,则会进入死循环
#因为__init__里面的赋值会自动给调用__seattr__
#而self.name = value,又会调用__seattr__,导致无限递归
#另一方法是 self.__dict__[name] = value
def getArea(self):
return self.width *self.height
运行:
>>> c = Rectangle(3,6)
>>> c.getArea()
18
>>> c.square = 10 #定义一个属性square被设置时,value=10
>>> c.getArea()
100
>>> c.width
10
>>> c.height
10
>>>
再来巩固一下
class Count:
def __init__(self):
self.count = 0 #这个赋值操作会自动调用setattr操作
def __setattr__(self,name,value):
self.count +=1 #这个操作里面存在对count的运算,调用后self,count才真正设置,所以提示count不存在
运行:
>>> c = Count()
Traceback (most recent call last):
File "C:\Users\1\Desktop\python\11.py", line 3, in __init__
self.count = 0
File "C:\Users\1\Desktop\python\11.py", line 6, in __setattr__
self.count +=1
AttributeError: 'Count' object has no attribute 'count'
那么如何实现对类的属性的计数,检测对象有多少个属性
class Counter():
def __init__(self):
super().__setattr__('counter',0)
def __setattr__(self,name,value):
super().__setattr__('counter',self.counter+1)
super().__setattr__(name,value)
def __delattr__(self,name):
super().__setattr__('counter',self.counter-1)
super().__delattr__(name)
三、静态属性(标记,未学)
1、如何在继承的类中调用基类的属性——super()
2、继承的类是动态的该如何部署
为基类取别名,在继承时使用别名替代基类的名字
ABC=Baseclass
class A(ABC):
.....
3、类的静态属性
在类中直接定义的变量就是静态属性,静态属性调用的方法是,类名.属性
class C:
count = 0 #静态属性
def __init__(self):
C.count =C.count +1 #静态属性的调用
def getCount(self):
return C.count
运行:
>>> c =C()
>>> c.getCount ()
1
>>>
4、如何使用类的静态方法,静态方法属于特殊方法,在类名前面加上@staticmethod 静态方法不需要self参数,不会绑定到实例对象,实际就是节省开销
class C:
@staticmethod
def static(arg1,arg2,arg3):
print(arg1,arg2,arg3)
def nostatic(self):
print('abcdefg')
>>> c=C()
>>> c2 = C()
>>> c.static
<function C.static at 0x0000021F739D1168>
>>> c2.static
<function C.static at 0x0000021F739D1168> #c与c2的内存是同一个,节省了开销
>>> c.nostatic
<bound method C.nostatic of <__main__.C object at 0x0000021F739E0B88>>
>>> c2.nostatic
<bound method C.nostatic of <__main__.C object at 0x0000021F73A2F688>>
>>> c.static(1,2,3) #没有self参数
1 2 3
>>>