定制魔法方法

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模块了解得差不多了。

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

import time as t

class Timer():
    def __init__(self):
        self.unit=['年','月','天','小时','分钟','秒','星期','一年中的天数','夏令时']
        self.string='未开始比赛'
        self.last=[]
        self.begin=0
        self.end=0

    def __str__(self):
        return self.string

    __repr__=__str__    #这个方法前面说过,当调用方法时,会自动打印方法下的字符串

    def start(self):
        self.begin=t.localtime()
        self.string='请务必保证事先已调用stop()归零'
        print('计时开始...')

    def stop(self):
        if not self.begin:
            print('请务必保证事先已调用start()开始计时')
        else:
            self.end=t.localtime()
            self.result()
            print('计时结束')

    def result(self):
        self.last=[]
        self.string='运动员总共用时'
        for index in range(9):
            self.last.append(self.end[index]-self.begin[index])
            if self.last[index]:
                self.string += (str(self.last[index])+self.unit[index])

        self.begin=0
        self.end=0

    def __add__(self,other):
            string='运动员总共用时'
            result=[]
            for i in range(9):
                result.append(self.last[i]+other.last[i])
                print(result)
                if result[i]:
                    string += (str(result[i])+self.unit[i])
                    #print(string)
                    return string

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

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

#-*- coding:utf-8 -*-

import time

class Timer():
    def __init__(self):
        self.unit=['年','月','天','小时','分钟','秒']
        self.string='未开始比赛'
        self.last=[]
        self.begin=0
        self.end=0

    def __str__(self):
        return self.string

    __repr__=__str__    #这个方法前面说过,当调用方法时,会自动打印方法下的字符串

    def start(self):
        self.begin=time.localtime()
        self.string='请务必保证事先已调用stop()归零'
        #print('计时开始...')

    def stop(self):
        if not self.begin:
            print('请务必保证事先已调用start()开始计时')
        else:
            self.end=time.localtime()
            self.result()
            #print('计时结束')

    def result(self):
        self.last=[]
        self.string='总共用时'
        for i in range(6):
            self.last.append(self.end[i]-self.begin[i])
            if self.last[i]:
                self.string += (str(self.last[i])+self.unit[i])

        self.begin=0
        self.end=0

if __name__== '__main__':
    print('准备比赛,运动员上场')

    print('1号运动员就位')
    player1=Timer()

    print('2号运动员就位')
    player2=Timer()

    print('3号运动员就位')
    player3=Timer()

    print('4号运动员就位')
    player4=Timer()

    print('5号运动员就位')
    player5=Timer()

    print('各就各位,准备。。。。开始!')
    player1.start()
    player2.start()
    player3.start()
    player4.start()
    player5.start()

    time.sleep(9)   #这是time模块里的方法,作为暂时停顿,单位是秒

    player1.stop()

    time.sleep(0.5)

    player2.stop()

    time.sleep(0.5)

    player3.stop()

    time.sleep(0.5)

    player4.stop()

    time.sleep(0.5)

    player5.stop()

    print('所有运动员已经跑完百米,比赛结束')
    print('1号运动员的成绩为:',player1)
    print('2号运动员的成绩为:',player2)
    print('3号运动员的成绩为:',player3)
    print('4号运动员的成绩为:',player4)
    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. 从svn下载项目,并在tomcat启动

    1.需要先在本地安装mysql,并且启动成功(配置环境变量.客户端等). 2.需要下载小乌龟,需要从svn上下载项目. 3.安装eclipse,并且在eclipse上下载项目,会下载成两个聚合项目,不 ...

  2. 你(可能)不知道的web api

    你(可能)不知道的web api 简介 作为前端er,我们的工作与web是分不开的,随着HTML5的日益壮大,浏览器自带的webapi也随着增多.本篇文章主要选取了几个有趣且有用的webapi进行介绍 ...

  3. idea中切换svn地址不起作用

    由于公司换地儿,svn地址也跟着变化. 期望用idea能修改svn的地址,不至于重新checkout.网上很多说修改 vcs -> Subversion -> Relocate .把原来的 ...

  4. [深度学习]理解RNN, GRU, LSTM 网络

    Recurrent Neural Networks(RNN) 人类并不是每时每刻都从一片空白的大脑开始他们的思考.在你阅读这篇文章时候,你都是基于自己已经拥有的对先前所见词的理解来推断当前词的真实含义 ...

  5. go runtime.Gosched()的作用分析

    untime.Gosched()用于让出CPU时间片.这就像跑接力赛,A跑了一会碰到代码runtime.Gosched()就把接力棒交给B了,A歇着了,B继续跑. 看代码: package main ...

  6. linux nohup

    nohup RAILS_ENV=production bundle exec XXXX & nohup RAILS_ENV=production bundle exec XXXX >/d ...

  7. 3分钟看完Java 8——史上最强Java 8新特性总结之第一篇 函数式编程基础

    目录 · 行为参数化 · Lambda表达式 · 概况 · 函数式接口 · 类型推断 · 使用外层变量 · 方法引用 · 复合Lambda表达式 行为参数化 1. 理解函数式编程要先理解行为参数化. ...

  8. FCKEditor的使用步骤

    在线发布信息难免要用到在线编辑器,下面就说下在线编辑器的使用步骤: 1.下载FCK,这个不说了 2.把ZZGSEditor文件夹放到网站根目录 3.把FredCK.FCKeditorV2.dll文件放 ...

  9. MyBatis从入门到放弃三:一对一关联查询

    前言 简单来说在mybatis.xml中实现关联查询实在是有些麻烦,正是因为起框架本质是实现orm的半自动化. 那么mybatis实现一对一的关联查询则是使用association属性和resultM ...

  10. 为 Html 5 和 CSS 3.0 而生——Modernizr的介绍和使用

    传统浏览器目前不会被完全取代,令你难以将最新的 CSS3 或 HTML5 功能嵌入你的网站. Modernizr 正是为解决这一难题应运而生,作为一个开源的 JavaScript 库,Moderniz ...