定制魔法方法

1.什么是定制魔法方法

首先定制是什么意思呢?其实就是自定义了,根据我们想要的要求来自定义。而在python中,其实那些所谓的内置函数,内置方法,内置属性之类的其实也是自定义出来的,不过是龟数开发python时已经给出了,已经自带了基本能想到的功能都带有了,换句话就是已经给我们事先定义好了,要用的话,直接拿来就用就是,不需要我们自己再去定义。定制魔法方法就是自定义魔法方法了。但是必须遵循定制魔法方法的一些规则

2.怎么定制

说到定制魔法方法,那么魔法方法是哪里有的?类啊,要想定制魔法方法,那么必须得和类结合一起才行的

看一个简单的例子:

里面的__str__就是我们自己定制的魔法方法

看下还有哪些属性和方法呢?

我这里使用的是python3,前面说过了,因为在python3定义类时,即使不加object,python3也会默认给你把object基类加上,上面那些方法大部分都是继承object类的方法的。

不过这里要提一个魔法方法,前面忘了提了——__dict__

这个魔法方法是干什么的呢?是用于查看实例对象的属性的,格式:

对象名.__dict__#字典属性,与python内置的dir()函数功能有点类似

例:python3下

 

python2下:

但是如果是查看实例化的对象是空的

再看例子:

而使用__repr__魔法方法则不用print就可以直接返回

3.例子

场景:百米赛跑的运动会上,设置一个计时器,能准确无误的计时每个运动员跑完一百米后所用的时间,场上有5个赛道,有5个运动员同时比赛。只有一场比赛,用时较短者胜。

例子先放一边,既然需要计时器,那么首先这里得说个知识点——时间

在python中,通常三种方式来表示时间:

  • struct_time元组
  • 时间戳
  • 格式化的时间字符串

一、struct_time元组

1.什么事struct_time元组

这个元组很特殊,单独成类,但其实本质上是一个元组

2.怎么生成struct_time元组:使用time模块的localtime方法

这个元组共有九个元素,虽然都是使用=来连接,但它既不是字典也不是集合,就是哦这么特殊。

每个元素依次的含义:

索引(Index) 属性(Attribute) 值(Values)
0 tm_year(年) 比如2017
1 tm_mon(月) 1 - 12
2 tm_mday(日) 1 - 31
3 tm_hour(时) 0 - 23
4 tm_min(分) 0 - 59
5 tm_sec(秒) 0 - 61
6 tm_wday(weekday) 0 - 6(0表示周日)
7 tm_yday(一年中的第几天) 1 - 366
8 tm_isdst(是否是夏令时) 默认为-1

最长用的就是前6个,后面三个基本不怎么用

二、时间戳(注意是戳,不是截取的截)

1.什么是时间戳

时间戳(timestamp),一个能表示一份数据在某个特定时间之前已经存在的、 完整的、 可验证的数据,通常是一个字符序列,唯一地标识某一刻的时间。是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。通俗的讲, 时间戳是一份能够表示一份数据在一个特定时间点已经存在的完整的可验证的数据。 它的提出主要是为用户提供一份电子证据, 以证明用户的某些数据的产生时间。 在实际应用上, 它可以使用在包括电子商务、 金融活动的各个方面, 尤其可以用来支撑公开密钥基础设施的 “不可否认” 服务(来自百度百科解释)

2.时间戳怎么生成:用time模块的time方法

3.时间戳与时间之间的转换:

1)时间转换为时间戳:

  • 使用time模块的strptime方法将时间转为struct_time元组
  • 使用time模块的mktime方法将struct_time元组转为时间戳

2)时间戳转为时间:

  • 使用time模块的localtime方法将时间戳转为struct_time元组
  • 使用time模块的strftime方法将struct_time元组转为时间

其实你有没有发现,时间戳和时间之间相互转换的中途都会使用struct_time元组作为中转站,就像字符编码里的unicode一样

三、格式化的时间字符串

时间也是字符串,作为一个特殊的时间字符串

格式化成新的格式的时间字符串

这里的【"%Y-%m-%d %H:%M:%S"】和【"%Y-%m-%d-%H-%M-%S"】里的%Y,%m,%d,%H,%M,%S都是定死了的,不能更改,就像%s代表字符串,%f代表浮点型数一样

符号

含义

%a

本地(locale)简化星期名称

%A

本地完整星期名称

%b

本地简化月份名称

%B

本地完整月份名称

%c

本地相应的日期和时间表示

%d

一个月中的第几天(01 - 31)

%H

一天中的第几个小时(24小时制,00 - 23)

%I

第几个小时(12小时制,01 - 12)

%j

一年中的第几天(001 - 366)

%m

月份(01 - 12)

%M

分钟数(00 - 59)

%p

本地am或者pm的相应符

%S

秒(01 - 61)

%U

一年中的星期数。(00 - 53星期天是一个星期的开始。)第一个星期天之前的所有天数都放在第0周。

%w

一个星期中的第几天(0 - 6,0是星期天)

%W

和%U基本相同,不同的是%W以星期一为一个星期的开始。

%x

本地相应日期

%X

本地相应时间

%y

去掉世纪的年份(00 - 99)

%Y

完整的年份

%Z

时区的名字(如果不存在为空字符)

%%

‘%'字符

注意:

  • “%p”只有与“%I”配合使用才有效果
  • 文档中强调确实是0 - 61,而不是59,闰年秒占两秒
  • 当使用strptime()函数时,只有当在这年中的周数和天数被确定的时候%U才会被计算

有了以上的解析,相信你已经对time模块了解得差不多了。

那么接着看例子,我们要解决那个计时器,就必须得具备上面的知识点,才能解决这个问题

  1. import time as t
  2.  
  3. class Timer():
  4. def __init__(self):
  5. self.unit=['年','月','天','小时','分钟','秒','星期','一年中的天数','夏令时']
  6. self.string='未开始比赛'
  7. self.last=[]
  8. self.begin=0
  9. self.end=0
  10.  
  11. def __str__(self):
  12. return self.string
  13.  
  14. __repr__=__str__ #这个方法前面说过,当调用方法时,会自动打印方法下的字符串
  15.  
  16. def start(self):
  17. self.begin=t.localtime()
  18. self.string='请务必保证事先已调用stop()归零'
  19. print('计时开始...')
  20.  
  21. def stop(self):
  22. if not self.begin:
  23. print('请务必保证事先已调用start()开始计时')
  24. else:
  25. self.end=t.localtime()
  26. self.result()
  27. print('计时结束')
  28.  
  29. def result(self):
  30. self.last=[]
  31. self.string='运动员总共用时'
  32. for index in range(9):
  33. self.last.append(self.end[index]-self.begin[index])
  34. if self.last[index]:
  35. self.string += (str(self.last[index])+self.unit[index])
  36.  
  37. self.begin=0
  38. self.end=0
  39.  
  40. def __add__(self,other):
  41. string='运动员总共用时'
  42. result=[]
  43. for i in range(9):
  44. result.append(self.last[i]+other.last[i])
  45. print(result)
  46. if result[i]:
  47. string += (str(result[i])+self.unit[i])
  48. #print(string)
  49. return string

代码是用于计算一个运动员比赛用时的,开始测试结果:

由于在实际开发中都会先测试再真正投入使用。这里没有问题,进行真正使用

  1. #-*- coding:utf-8 -*-
  2.  
  3. import time
  4.  
  5. class Timer():
  6. def __init__(self):
  7. self.unit=['年','月','天','小时','分钟','秒']
  8. self.string='未开始比赛'
  9. self.last=[]
  10. self.begin=0
  11. self.end=0
  12.  
  13. def __str__(self):
  14. return self.string
  15.  
  16. __repr__=__str__ #这个方法前面说过,当调用方法时,会自动打印方法下的字符串
  17.  
  18. def start(self):
  19. self.begin=time.localtime()
  20. self.string='请务必保证事先已调用stop()归零'
  21. #print('计时开始...')
  22.  
  23. def stop(self):
  24. if not self.begin:
  25. print('请务必保证事先已调用start()开始计时')
  26. else:
  27. self.end=time.localtime()
  28. self.result()
  29. #print('计时结束')
  30.  
  31. def result(self):
  32. self.last=[]
  33. self.string='总共用时'
  34. for i in range(6):
  35. self.last.append(self.end[i]-self.begin[i])
  36. if self.last[i]:
  37. self.string += (str(self.last[i])+self.unit[i])
  38.  
  39. self.begin=0
  40. self.end=0
  41.  
  42. if __name__== '__main__':
  43. print('准备比赛,运动员上场')
  44.  
  45. print('1号运动员就位')
  46. player1=Timer()
  47.  
  48. print('2号运动员就位')
  49. player2=Timer()
  50.  
  51. print('3号运动员就位')
  52. player3=Timer()
  53.  
  54. print('4号运动员就位')
  55. player4=Timer()
  56.  
  57. print('5号运动员就位')
  58. player5=Timer()
  59.  
  60. print('各就各位,准备。。。。开始!')
  61. player1.start()
  62. player2.start()
  63. player3.start()
  64. player4.start()
  65. player5.start()
  66.  
  67. time.sleep(9) #这是time模块里的方法,作为暂时停顿,单位是秒
  68.  
  69. player1.stop()
  70.  
  71. time.sleep(0.5)
  72.  
  73. player2.stop()
  74.  
  75. time.sleep(0.5)
  76.  
  77. player3.stop()
  78.  
  79. time.sleep(0.5)
  80.  
  81. player4.stop()
  82.  
  83. time.sleep(0.5)
  84.  
  85. player5.stop()
  86.  
  87. print('所有运动员已经跑完百米,比赛结束')
  88. print('1号运动员的成绩为:',player1)
  89. print('2号运动员的成绩为:',player2)
  90. print('3号运动员的成绩为:',player3)
  91. print('4号运动员的成绩为:',player4)
  92. print('5号运动员的成绩为:',player5)

比赛计时器

结果:

你会想,等会儿,本篇博文主题不是定制魔法方法吗?这里用到了?

是的用到了,不过用的少,只有一个__repr__ = __str__  ,慢慢来,在面向对象章节了还有很多知识点。

那么你可能会想,怎么5个运动员的开始起跑和到达终点都是手动控制的,可以同时进行吗?可以的,后面说到多线程和异步的时候就会说到,这里先暂时忽略本问题吧

PS:我的博文也会尽量把知识面覆盖完,有时候为了把相关知识全部拿出来,所以思维都是一个网状式的,可能突然想起什么去解析这里然后同时又忘记那里就没有拿出来解析,这个也请见谅,我只是一个自学编程的无名人士,不是大佬,也没有多少写博文的经验,有时候为了说明一个知识点,自创一个例子来举例也可以能举的不是很好(比如上面的计时器例子,我想了很久才想到和自定义魔法方法沾边的,能力有限,没办法),那些例子也不知道你们能不能看懂,总之,以后继续努力

关于面向对象编程的主线知识点基本算覆盖完了,后期我打算随机出一两篇巩固复习知识点的博文,希望尽量能把面向对象说清楚,尽量把所有相关知识点说全,因为真的很重要。

洗礼灵魂,修炼python(40)--面向对象编程(10)—定制魔法方法+time模块的更多相关文章

  1. Python:面向对象编程3 定制类(有更新)

    Python:面向对象编程3  定制类(有更新) ⚠️本文主要内容为对Data model相关知识点的提取学习记录.(内容来自文档和部分网页教程案例) ⚠️:这个连接指向<流畅的python&g ...

  2. python基础——面向对象编程

    python基础——面向对象编程 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的 ...

  3. Python之面向对象编程学习

    不知不觉,学到了python的面向对象编程思想.今天我们来讨论下面向对象编程的思想. 顾名思义,面向对象,就是面向于对象,这里所说的对象不是你现实生活中你的女朋友,你的老婆,你的爱人,在编程的世界里面 ...

  4. python中的魔术属性与魔法方法

    1.魔法属性 · 1.1__doc__魔法属性  表示类的描述信息 class Fo: """ 这是今天第一个魔术属性__doc__""" ...

  5. python基础-面向对象编程

    一.三大编程范式 编程范式即编程的方法论,标识一种编程风格 三大编程范式: 1.面向过程编程 2.函数式编程 3.面向对象编程 二.编程进化论 1.编程最开始就是无组织无结构,从简单控制流中按步写指令 ...

  6. python之面向对象编程

    1.面向对象介绍: 世界万物,皆可分类 世界万物,皆为对象 只要是对象,就肯定属于某种类 只要是对象,就肯定有属性 2. 面向对象的几个特性: class类: 一个类即对一类拥有相同属性的对象的抽象, ...

  7. python(8):面向对象编程

    有三种程序类型: (1)面向过程:按照一定的逻辑顺序,一步步垒代码 (2)面向函数:对用常用的计算,建立函数避免重复 (3)面向对象: 函数的集合,对函数进行分类和封装 (一) 抽象 抽象: 哈巴狗, ...

  8. Python基础 — 面向对象编程基础

    目录 1. 面向对象编程基础 2. 定义类和创建对象 3. init() 方法 4. 魔法方法 5. 访问可见性问题 5. 练习 1. 面向对象编程基础 把一组数据结构和处理它们的方法组成对象(obj ...

  9. python笔记 面向对象编程从入门到高级

    目录: 一.概念 二.方法    2.1组合 2.2继承 2.3多态 2.4封装 2.5归一化设计 三.面向对象高级   3.1   反射(自省) 3.2   内置方法__getatter__, __ ...

随机推荐

  1. [EXP]Apache Tika-server < 1.18 - Command Injection

    #################################################################################################### ...

  2. WebSocket connection to 'ws://xx:9502/' failed:Error in connection establishment:net::ERR_CONNECTION_TIMED_OUT

    1.首先看能否ping通服务器 2.telnet xx 9502之后能不能连通 3.如果连不通有可能是防火墙的问题 可以试试清空防火墙规则,或者关闭防火墙 iptables -F

  3. Android的Fragment中的互相通信-桥梁activity

    Android的Fragment中的互相通信-桥梁activity 效果图如下: 项目结构图如下: Fragment1: package com.demo.fragmenttongxin; impor ...

  4. 7.28-说说对javaweb的感想吧

    接触了几个月的java,和javaweb. 感想1:发现生活顿时充实了很多,时间照样在过,日落日出,但是手里面有学的,有可以让自己开心地码出理想的效果,这是很不错的结局. 发现自己再也不回去和伙伴们撸 ...

  5. TCP/IP 笔记 - 地址解析协议

    地址解析协议(ARP)提供了一种在IPv4地址和各种网络技术使用的硬件地址之间的映射.ARP仅用于IPv4,IPv6使用邻居发现协议,它被合并入ICMPv6.地址解析是发现两个地址之间的映射关系的过程 ...

  6. C#7.0--引用返回值和引用局部变量

    一.在C#7.0以上版本中,方法的返回值可以通过关键字ref指定为返回变量的引用(而不是值)给调用方,这称为引用返回值(Reference Return Value,或ref returns): 1. ...

  7. CSS 基础:定位元素(3)<思维导图>

    这段时间利用一下间隙时间学习了CSS的基础知识,主要目的是加深对CSS的理解,虽然个人主要工作基本都是后台开发,但是个人觉得系统学习一下CSS的基础还是很有必要的.下面我学习CSS时做的思维导图(全屏 ...

  8. Docker上运行MySQL服务

    1.搜索MySQL镜像 $ docker search mysql INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED docker.io docker.i ...

  9. Linux下搭建DNS缓存服务器

    CentOS 6.10搭建本地DNS缓存服务器系统环境 1 [root@test ~]# cat /etc/redhat-release 2 CentOS release 6.10 (Final) 3 ...

  10. 自己动手实现java数据结构(二) 链表

    1.链表介绍 前面我们已经介绍了向量,向量是基于数组进行数据存储的线性表.今天,要介绍的是线性表的另一种实现方式---链表. 链表和向量都是线性表,从使用者的角度上依然被视为一个线性的列表结构.但是, ...