一、定制类,实质就是我们自己重写特殊函数

看到类似__slots__这种形如__xxx__的变量或者函数名就要注意,这些在Python中是有特殊用途的。

__slots__我们已经知道怎么用了,__len__()方法我们也知道是为了能让class作用于len()函数。

除此之外,Python的class中还有许多这样有特殊用途的函数,可以帮助我们定制类。

二、__len__()方法

>>> class MyStr(str):
  def __init__(self, s):
  self.__s = s
  def __len__(self):
  return len(self.__s) - >>> s = MyStr('abc')
>>> len(s)

三、__str__()方法

>>> class Student(object):
... def __init__(self, name):
... self.name = name
... def __str__(self):
... return 'Student object (name: %s)' % self.name
...
>>> print(Student('Michael'))
Student object (name: Michael)

四、__repr__()方法

>>> s = Student('Michael')
>>> s
<__main__.Student object at 0x109afb310>

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

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

class Student(object):
def __init__(self, name):
self.name = name
def __str__(self):
return 'Student object (name=%s)' % self.name
__repr__ = __str__

五、__iter__()方法

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

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

class Fib(object):
def __init__(self):
self.a, self.b = , # 初始化两个计数器a,b def __iter__(self):
return self # 实例本身就是迭代对象,故返回自己 def __next__(self):
self.a, self.b = self.b, self.a + self.b # 计算下一个值
if self.a > : # 退出循环的条件
raise StopIteration()
return self.a # 返回下一个值
>>> for n in Fib():
... print(n)
... ...

六、__getitem__()方法

class Fib(object):
def __getitem__(self, n):
if isinstance(n, int): # n是索引
a, b = ,
for x in range(n):
a, b = b, a + b
return a
if isinstance(n, slice): # n是切片
start = n.start
stop = n.stop
if start is None:
start =
a, b = ,
L = []
for x in range(stop):
if x >= start:
L.append(a)
a, b = b, a + b
return L

但是没有对step参数作处理,

也没有对负数作处理,所以,要正确实现一个__getitem__()还是有很多工作要做的。

此外,如果把对象看成dict__getitem__()的参数也可能是一个可以作key的object,例如str

与之对应的是__setitem__()方法,把对象视作list或dict来对集合赋值。最后,还有一个__delitem__()方法,用于删除某个元素。

总之,通过上面的方法,我们自己定义的类表现得和Python自带的list、tuple、dict没什么区别,这完全归功于动态语言的“鸭子类型”,不需要强制继承某个接口。

python 面向对象九 定制类的更多相关文章

  1. Python面向对象之接口类(抽象类)

    Python面向对象之接口类(抽象类):就是制定一个规范. 比如定义了一个接口类(抽象类)(他们是不可以进行实例化的,这就是他为什么是制定一个规范的原因). 他的定义是需要abc模块,要变的就是他的方 ...

  2. Python面向对象06 /元类type、反射、函数与类的区别、特殊的双下方法

    Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3 ...

  3. Python面向对象总结及类与正则表达式

    Python3 面向对象 一丶面向对象技术简介 类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 方法:类中定义的函数. 类变 ...

  4. Python面向对象编程、类

    一.面向对象编程 面向对象--Object Oriented Programming,简称oop,是一种程序设计思想.在说面向对象之前,先说一下什么是编程范式,编程范式你按照什么方式来去编程,去实现一 ...

  5. python学习(八)定制类和枚举

    `python`定制类主要是实现特定功能,通过在类中定义特定的函数完成特定的功能. class Student(object): def __init__(self, name): self.name ...

  6. Python面向对象 --- 新旧式类、私有方法、类属性和类方法、静态方法

    一.Python面向对象中的新旧式类 1)新式类(推荐使用):在定义类时,类后边括号里要继承基类(object).在python3.x中若没有指定父类,会默认使用的是object作为基类:在pytho ...

  7. Python面向对象-概念、类、实例

    OOP——Object Oriented Programming,面向对象编程,是一种程序设计思想.该思想将对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 区别于面向过程的程序设计即把计 ...

  8. Python基础(定制类)

    文章转载自廖雪峰老师Python课程博客,仅供学习参考使用看到类似__slots__这种形如__xxx__的变量或者函数名就要注意,这些在Python中是有特殊用途的. __slots__我们已经知道 ...

  9. Python面向对象1:类与对象

    Python的面向对象- 面向对象编程 - 基础 - 公有私有 - 继承 - 组合,Mixin- 魔法函数 - 魔法函数概述 - 构造类魔法函数 - 运算类魔法函数 # 1. 面向对象概述(Objec ...

随机推荐

  1. [Bzoj1083][SCOI2005]互不侵犯king(状压dp)

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4595  Solved: 2664[Submit][ ...

  2. Java的基本运算符

    以下内容引用自http://wiki.jikexueyuan.com/project/java/basic-operators.html: Java针对操控变量提供了一组丰富的运算符.可以将所有的Ja ...

  3. win7电脑定时开机设置方法

    在BIOS设置主界面中选择“Power Management Setup”,进入“电源管理”窗口. 注:缺省情况下,“Resume By Alarm”定时开机选项是关闭的. 将鼠标移到“Resume ...

  4. 各种Js插件汇总;JavaScript插件

    1.jquery信息提示插件: https://blog.csdn.net/u013517229/article/details/78291841 http://www.jqueryfuns.com/ ...

  5. 关闭Windows 2003/2008中IE增强的安全配置的方法

           在使用Windows Server 2003/2008操作系统时,打开IE浏览网页时,发现浏览器总提示 "是否需要将当前访问的网站添加到自己信任的站点中去",要是不信 ...

  6. protobuf 之 MessageLite 接口摘录

    class LIBPROTOBUF_EXPORT MessageLite { public: inline MessageLite() {} virtual ~MessageLite(); // Ba ...

  7. vue-cli中process.env配置以及打包本地运行或者线上运行配置

    我们知道打包默认npm run build,可是打包后点击dist文件中index.html一片空白.问题在于路径问题.我们在工程文件的最外层增加文件.env.production这个文件就是这么奇怪 ...

  8. List<Guid?> a = new List<Guid?>();

    正常写法 泛型 类型 为 Guid? List<Guid?> a = new List<Guid?>(); Guid? b = null; Nullable<Guid&g ...

  9. Socketclient与服务端

    package test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamR ...

  10. 一个很小的C++写的MVC的例子

    #include<iostream> #include<vector> //get namespace related stuff using std::cin; using ...