python-类的定制

python-类的定制

1.看到类似__slots__这种形如__xxx__的变量或者函数名就要注意,这些在Python中是有特殊用途的。__slots__我们已经知道怎么用了,__len__()方法我们也知道是为了能让class作用于len()函数。除此之外,Python的class中还有许多这样有特殊用途的函数,可以帮助我们定制类。

1)__str__,定制对象自身打印的字符串

>>> class S(object):def __init__(self,name):self.name = name>>> print(S('SB'))
<__main__.S object at 0x0000000002E7F0F0>
>>> class S(object):def __init__(self,name):self.name = namedef __str__(self):return 's object(name=%s)' % self.name>>> print(S('md'))
s object(name=md)

2)这是因为直接显示变量调用的不是__str__(),而是__repr__(),两者的区别是__str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串,也就是说,__repr__()是为调试服务的。

解决办法是再定义一个__repr__()。但是通常__str__()__repr__()代码都是一样的,所以,有个偷懒的写法:

<__main__.S object at 0x0000000002E7F0F0>
>>> class S(object):def __init__(self,name):self.name = namedef __str__(self):return 's object(name=%s)' % self.name>>> print(S('md'))
s object(name=md)
>>> a = S('MJ')
>>> a
<__main__.S object at 0x0000000002C98390>
>>> class S(object):def __init__(self,name):self.name = namedef __str__(self):return 's object(name=%s)' % self.name__repr__ = __str__
>>> a = S('MJ')
>>> a
s object(name=MJ)

3)__iter__

如果一个类想被用于for ... in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的__next__()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。

我们以斐波那契数列为例,写一个Fib类,可以作用于for循环:

class Fib(object):def __init__(self):self.a,self.b = 0,1#初始化两个计数器a,bdef __iter__(self):return self #实例本身就是迭代对象,返回自己def __next__(self):self.a,self.b = self.b,self.a+self.b #计算下一个值if self.a > 10000: #循环推出条件raise StopIteration()return self.a #返回下一个值>>> for n in Fib():print(n)1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765

4)__getitem__,要表现得像list那样按照下标取出元素,需要实现__getitem__()方法:

class Fib(object):def __init__(self):self.a,self.b = 0,1#初始化两个计数器a,bdef __iter__(self):return self #实例本身就是迭代对象,返回自己def __next__(self):self.a,self.b = self.b,self.a+self.b #计算下一个值if self.a > 10000: #循环推出条件raise StopIteration()return self.a #返回下一个值
def __getitem__(self,n):a,b = 1,1for x in range(n):a,b = b,a+breturn a>>> f = Fib()>>> f[0]1
>>> f[2]2
>>> f[3]3
>>> f[4]5
>>> f[8]34
>>> f[100]573147844013817084101

5)__getattr__,python还有另一个机制,那就是写一个__getattr__()方法,动态返回一个属性。修改如下:当调用不存在的属性时,比如score,Python解释器会试图调用__getattr__(self, 'score')来尝试获得属性,这样,我们就有机会返回score的值:

注意,只有在没有找到属性的情况下,才调用__getattr__,已有的属性,比如name,不会在__getattr__中查找。

此外,注意到任意调用如s.abc都会返回None,这是因为我们定义的__getattr__默认返回就是None。要让class只响应特定的几个属性,我们就要按照约定,抛出AttributeError的错误:

>>> class st(object):def __init__(self):self.name = 'MJ'def __getattr__(self,attr):if attr == 'score':return 99>>> s = st()>>> s.name'MJ'
>>> s.score99
>>> s.age>>> s.page

6)如果要写SDK,给每个URL对应的API都写一个方法,那得累死,而且,API一旦改动,SDK也要改。

利用完全动态的__getattr__,我们可以写出一个链式调用:

class Chain(object):def __init__(self,path=''):self._path = pathdef __getattr__(self,path):return Chain('%s/%s' % (self._path,path))def __str__(self):return self._path__repr__ = __str__>>> ch = Chain()>>> ch.status.user.timeline.list/status/user/timeline/list

7)__call__一个对象实例可以有自己的属性和方法,当我们调用实例方法时,我们用instance.method()来调用。能不能直接在实例本身上调用呢?在Python中,答案是肯定的。

任何类,只需要定义一个__call__()方法,就可以直接对实例进行调用。请看示例:

class tt(object):def __init__(self,name):self.name = namedef __call__(self):print("My name is %s " % self.name)>>> t()My name is mg 

8)__call__()还可以定义参数。对实例进行直接调用就好比对一个函数进行调用一样,所以你完全可以把对象看成函数,把函数看成对象,因为这两者之间本来就没啥根本的区别。

如果你把对象看成函数,那么函数本身其实也可以在运行期动态创建出来,因为类的实例都是运行期创建出来的,这么一来,我们就模糊了对象和函数的界限。

那么,怎么判断一个变量是对象还是函数呢?其实,更多的时候,我们需要判断一个对象是否能被调用,能被调用的对象就是一个Callable对象,比如函数和我们上面定义的带有__call__()的类实例:通过callable()函数,我们就可以判断一个对象是否是“可调用”对象。

>>> callable(t)True
>>> callable(max)True
>>> callable([1,2,3])False
>>> callable(None)False
>>> callable('str')False

9)

Python的class允许定义许多定制方法,可以让我们非常方便地生成特定的类。

本节介绍的是最常用的几个定制方法,还有很多可定制的方法,请参考Python的官方文档。

posted on 2018-09-14 21:54 lovejobs 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/huipengbo/p/9649182.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/464970.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

性能强悍的MCU,主频干到GHz

目前有两款高性能MCU印象深刻&#xff0c;不是多核心就是主频上1GHz。这也许是为了满足一些高数据吞吐量但仍需高实时性的需求吧。比如机械臂。一、第一款是来自于TI的Sitara AM2x&#xff0c;如型号为AM2434的单片机&#xff0c;拥有四个800MHz的核心&#xff0c;官方称为双核…

windows2003安全设置

一、分区规划 所有分区采用NTFS格式&#xff0c;NTFS在空间的利用、安全和性能方面比FAT格式都有较大的提升。建议分三个区。系统在C盘&#xff0c;空间15G-20G&#xff1b;D/E盘平分剩余空间&#xff0c;重要程序和数据库程序安装在D盘&#xff0c;E盘放临时文件和工具文件以及…

C语言无符号数运算问题

C语言中有符号数和无符号数进行运算&#xff08;包括逻辑运算和算术运算&#xff09;默认会将有符号数看成无符号数进行运算&#xff0c;其中算术运算默认返回无符号数&#xff0c;逻辑运算当然是返回0或1了。 unsigned int和int进行运算 直接看例子来说明问题吧 复制代码 #i…

Unity3D_(游戏)控制物体的上、下、左、右移动

通过键盘上↑、↓、←、→实现对物体的控制 using System.Collections; using System.Collections.Generic; using UnityEngine;public class Gary_Text : MonoBehaviour {public Transform WuTi;public float speed 1;// Use this for initializationvoid Start () {}// Upda…

糟糕的C语言睡眠排序算法

不知道大家知道这个算法没有&#xff0c;就是靠睡觉完成排序的。比如数字1 4 3&#xff0c;第一个数字1的时候&#xff0c;创建一个线程&#xff0c;然后让线程休眠1个时间单位&#xff0c;依次是 4 和 3个单位。因为睡眠的时间不同&#xff0c;线程醒的时间也不同。3会比4先醒…

Rocchio算法

其基本思想是使用训练集为每个类构造一个原型向量&#xff0c;构造方法如下&#xff1a;给定一个类&#xff0c;训练集中所有属于这个类的文档对应向量的分量用正数表示&#xff0c;所有不属于这个类的文档对应向量的分量用负数表示&#xff0c;然后把所有的向量加起来&#xf…

C语言定义:__DATE__和_TIME__

/******************************************************************** > File Name: 05-ymd.c* > Author: fly* > Mail: XXXXXXXXicode.com在这里插入代码片* > Create Time: Thu Sep 7 16:43:30 2017**********************************************…

写给小白看的,逆向工程怎么上路?

什么是逆向工程大家好&#xff0c;我是写代码的篮球&#xff0c;这篇文章转自小白哥的文章。给大家出一道思考题&#xff1a;用C语言设计一个程序&#xff0c;验证输入的密码是否是“12345678”&#xff0c;如果验证成功&#xff0c;就输出“success”&#xff0c;如果验证失败…

vue中,点击button按钮后,页面上的input框再次自动获取焦点

需求&#xff1a;点击button按钮&#xff0c;录入成功后&#xff0c;页面上的input框自动聚焦&#xff0c;快速进行下一次录入&#xff0c;提高效率 开始尝试了几种方法都没有成功 一、首先想到的用vue指令 v-focus&#xff0c;然而没有成功 <Input v-model"book.isbnO…

线程、同步与锁——Mutex想说爱你不容易

除了Lock&#xff08;&#xff09;、Monitor之外&#xff0c;我们最长用的就是Mutex了&#xff0c;但是玩不好Mutex就总会造成死锁或者AbandonedMutexException&#xff08;我就玩的不怎么好&#xff0c;在并发性访问测试的时候总是遇到关于Mutex的问题&#xff0c;各位线虫见笑…

STM32F4 串口DMA

串口DMA方式收发 笔者使用的是STM32F407VET6&#xff0c;共包含6路串口&#xff0c;页尾处程序已将全部串口的DMA收发配置完成&#xff0c;本文仅以串口1为例进行讲解。&#xff08;查看代码可直接跳至第二节或页尾处下载&#xff09; 1 STM32F4 DMA 简介 DMA&#xff0c;全称为…

在广州的几天

我前两天写了文章说过&#xff0c;我大伯去世&#xff0c;然后我请假了几天去广州。这次去广州&#xff0c;挺感慨的&#xff0c;顺便记录下自己的一些想法。广州限行广州是限行的&#xff0c;但是广州的限行我觉得很人性&#xff0c;如果是外地车牌&#xff0c;你可以在广州行…

由马化腾谈“微博修改功能”,看什么是优秀的产品经理

我仔细阅读过马化腾的的简历&#xff0c;他是一位技术出身的企业家。也是腾讯最大的产品经理,大家都知道产品经理的对产品的重要性那是不言而喻的&#xff0c;而产品是公司的灵魂。 今天早上起床&#xff0c;看到马化腾先生更新的微博。有位网络公司的CTO建议腾讯微博加一个修改…

flask 必知必会

在局域网中让其它电脑访问我的网站 from flask import Flaskapp Flask(__name__)app.route(/) def hello_world():return hello worldif __name__ __main__:app.run(debugTrue,host0.0.0.0,port9000) 转载于:https://www.cnblogs.com/wuheng-123/p/9665004.html

超酷的红外小车

推荐阅读&#xff1a;专辑|Linux文章汇总专辑|程序人生专辑|C语言我的知识小密圈关注公众号&#xff0c;后台回复「1024」获取学习资料网盘链接。欢迎点赞&#xff0c;关注&#xff0c;转发&#xff0c;在看&#xff0c;您的每一次鼓励&#xff0c;我都将铭记于心~

KEIL编译生成bin文件,并输出内存使用情况

一、STM32CubeMX生成的代码输出bin文件 输出bin文件&#xff1a; Run#1框填入的是&#xff1a;fromelf.exe空格–bin空格-o空格"$LL.bin"空格"#L"。“–bin”是两根英文短杆。 fromelf.exe --bin -o "$LL.bin" "#L"编译的时候&#x…

CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现

CRC16算法系列文章&#xff1a; CRC16算法之一&#xff1a;CRC16-CCITT-FALSE算法的java实现 CRC16算法之二&#xff1a;CRC16-CCITT-XMODEM算法的java实现 CRC16算法之三&#xff1a;CRC16-CCITT-MODBUS算法的java实现 功能 实现CRC16-CCITT-MODBUS算法 支持int、short类型…

建议去华为

提问&#xff1a;老师&#xff0c;您好&#xff01;我现在手里有两个offer&#xff0c;正在艰难抉择中&#xff0c;一个是小米的相机图像调校工程师&#xff08;camera tuning&#xff09;&#xff0c;工作地在深圳&#xff0c;工资是12k*14&#xff0c;还有大概700元的餐补&am…

Stimulsoft reports .net中创建变量

Stimulsoft reports .net中创建变量<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />变量中request from user 的使用&#xff1a;可以使你在外面指定日期的选择。根据用户需要去选择不同的条件。报表中code代码中也可以使用代码…

STM32CubeMx官网下载HAL库文档资料

1、直接搜STMCubeMxFxx即可。https://www.st.com/zh/embedded-software/stm32cubef4.html#documentation