python 新式类的学习随笔-定制类的特殊方法(2)
2017-11-03 19:18
696 查看
这部分大部分都是转载自python学习(7)定制类的特殊方法,加了一些自己的理解。
形如__xxx__的函数是类的特殊方法。常需要修改的特殊方法有下面这些:
PS:下划线的几种用法
说一下几种常用的:
1.名称前的单下划线(_strri):程序员使用名称前的单下划线,用于指定该名称属性为“私有”。如果你写了代码“from
<模块/包名> import *”,那么以“_”开头的名称都不会被导入,除非模块或包中的“__all__”列表显式地包含了它们。
2.名称前的双下划线(__strri):名称(具体为一个方法名)前双下划线(__)的用法并不是一种惯例,对解释器来说它有特定的意义。Python中的这种用法是为了避免与子类定义的名称冲突。Python文档指出,“__spam”这种形式(至少两个前导下划线,最多一个后续下划线)的任何标识符将会被“_classname__spam”这种形式原文取代,在这里“classname”是去掉前导下划线的当前类名。例如下面的例子:
>>> class A(object): ... def _internal_use(self): ... pass ... def __method_name(self): ... pass ... >>> dir(A()) ['_A__method_name', ..., '_internal_use']正如所预料的,“_internal_use”并未改变,而“__method_name”却被变成了“_ClassName__method_name”。此时,如果你创建A的一个子类B,那么你将不能轻易地覆写A中的方法“__method_name”。
>>> class B(A): ... def __method_name(self): ... pass ... >>> dir(B()) ['_A__method_name', '_B__method_name', ..., '_internal_use']3.名称前后的双下划线(__init__):
这种用法表示Python中特殊的方法名。其实,这只是一种惯例,对Python系统来说,这将确保不会与用户自定义的名称冲突。通常,你将会覆写这些方法,并在里面实现你所需要的功能,以便Python调用它们。例如,当定义一个类时,你经常会覆写“__init__”方法。
虽然你也可以编写自己的特殊方法名,但不要这样做。
>>> class C(object): ... def __mine__(self): ... pass ... >>> dir(C) ... [..., '__mine__', ...]
下面转入正题
__str__()
print语句输出的结果。
__repr__()
命令行直接输入类名的输出结果。class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
def __str__(self):
return '(Person: %s, %s)' % (self.name, self.gender)
__repr__ = __str__
p = Person('Bob', 'male')
print p
>>> p
输出:
(Person: Bob, male)
(Person: Bob, male)
__cmp__()
类的比较规则。class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
def __cmp__(self, s):
if self.score < s.score :
return -1
elif self.score > s.score :
return 1
else:
return 0
__len__()
类似list的类返回的元素数量。class Students(object):
def __init__(self, *args):
self.names = args
def __len__(self):
return len(self.names)
ss = Students('Bob', 'Alice', 'Tim')
print len(ss)
输出:3
数学运算符
__add__()、__sub__()、__mul__()、__div__()有理数的加减乘除:
def gcs(a,b,c=1):
if 0==a%2 and 0==b%2:
return gcs(a/2,b/2,c*2);
s = abs(a-b)
m = min(a,b)
if s == m:
return m*c
return gcs(s,m,c)
class Rational(object):
def __init__(self, p, q):
self.p = p
self.q = q
def __add__(self, r):
return Rational(self.p * r.q + self.q * r.p, self.q * r.q)
def __sub__(self, r):
return Rational(self.p * r.q - self.q * r.p, self.q * r.q)
def __mul__(self, r):
return Rational(self.p * r.p, self.q * r.q)
def __div__(self, r):
return Rational(self.p * r.q , self.q * r.p)
类型转换
__int__()、__float__()等把有理数转换为整数和浮点数:
class Rational(object):
def __init__(self, p, q):
self.p = p
self.q = q
def __int__(self):
return self.p // self.q
def __float__(self):
return self.p*1.0/self.q
@property装饰器与@score.setter装饰器
一起使用,用于把getter和setter方法变成属性。class Student(object):
@property
def score(self):
return self._score
@score.setter
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
s = Student()
s.score = 60 # OK,实际转化为s.set_score(60)
s.score # OK,实际转化为s.get_score()
s.score = 9999
输出:
60
Traceback (most recent call last):
...
ValueError: score must between 0 ~ 100!
__slots__()
指定一个类允许的属性列表。class Person(object):
__slots__ = ('name', 'gender')
__call__()
把一个类变成一个可调用的对象。class ImFunc(object):
def __call__(self,words):
print 'i say %s' % words
imfunc = ImFunc()
imfunc('what the func?') #把类当函数使用
class Addnum(object):
def __init__(self):
self.num = 0
def __call__(self,num = 1):
self.num += num
def __str__(self):
return 'num:{}'.format(self.num)
__repr__ = __str__
>>> a = Addnum() >>> print a num:0 >>> a()把类当做一个函数来使用。
每次调用a()一次,就相当于调用一次 __call__()。
print a()返回的是__str__()的内容,并不会运行。
print a() None >>> a.num 2 >>> a.num 2 >>> a.num 2 >>> a() >>> a.num 3 >>> a(5) >>> a.num 8
相关文章推荐
- python 新式类学习随笔-定制类的特殊方法(1)
- Python学习29:使用特殊的方法定制类(类似于c++的运算符重载)
- python学习(7)定制类的特殊方法
- 【Python基础】Python面向对象 - 4 - 定制类的特殊方法
- 学习python的第三十六天-OS模块,特殊的方法
- Python学习笔记(二)——特殊方法
- python中实现定制类的特殊方法总结
- python中实现定制类的特殊方法总结
- Python学习笔记1:数据模型和特殊方法(魔术方法)
- Python学习笔记(九)——Python _init_特殊方法和模块
- python 新式类学习随笔-装饰器(3)
- python中的用来定制类的特殊方法的含义
- Python学习笔记1:数据模型和特殊方法(魔术方法)
- Python学习笔记(二)——特殊方法(续)
- python开发学习-day07(面向对象之多态、类的方法、反射、新式类and旧式类、socket编程)
- 【python学习笔记】Python自带特殊方法一览
- python中实现定制类的特殊方法总结
- Python 定制类的特殊方法与授权
- python 用特殊方法定制类
- python中的用来定制类的特殊方法的含义