python类的专有方法_Python——类的专有方法

Python除了自定义私有变量和方法外,还可以定义专有方法。专有方法是在特殊情况下或使用特殊语法时由python调用的,而不是像普通方法一样在代码中直接调用。看到形如__XXX__的变量或函数名时就需要注意下,这在python中是有特殊用途的

__init__ : 构造函数,在生成对象时调用

__del__ : 析构函数,释放对象时使用

__repr__ : 打印,转换

__setitem__ : 按照索引赋值

__getitem__: 按照索引获取值

__len__: 获得长度

__cmp__: 比较运算

__call__: 函数调用

__add__: 加运算

__sub__: 减运算

__mul__: 乘运算

__div__: 除运算

__mod__: 求余运算

__pow__: 乘方

1. __str__

定义一个 Student 类:

class Student(object):

def __init__(self, name):

self.name = name

print(Student('zth'))

执行结果:

1、由上面代码可以看出如果直接输出一个类的实例的话,得到的是一个特殊的字符串(程序开发者所用的)

2、如果要把一个类的实例变成str,就需要实现特殊方法__str__( )方法

3、__str__方法必须要return一个字符串类型的返回值,作为对实例对象的字符串描述

class Student(object):

def __init__(self, name):

self.name = name

def __str__(self):

return "学生的姓名:%s"%self.name

print(Student('zth'))

执行结果:

学生的姓名:zth

交互模式下:

>>> class Student(object):

... def __init__(self, name):

... self.name = name

...

... def __str__(self):

... return "学生的姓名:%s"%self.name

...

>>>

>>> print(Student('zth'))

学生的姓名:zth

>>>

>>> s = Student('zth')

>>>

>>> s

>>>

>>> print(s)

学生的姓名:zth

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

解决办法是再定义一个__repr__。通常__str__() 和 __repr__() 代码是一样的,可以如下简写:

>>> class Student(object):

... def __init__(self, name):

... self.name = name

...

... def __str__(self):

... return "学生的姓名:%s"%self.name

...

... __repr__ = __str__

...

>>>

>>> s = Student('zth')

>>>

>>> s

学生的姓名:zth

2. __iter__

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

如下:一个作用于 for 循环的斐波那契数列类:

class Fib(object):

def __init__(self):

self.a , self.b = 0,1 # 初始化两个计数器 a、b

def __iter__(self):

return self # 实例本身就是迭代对象。故返回自己

def __next__(self):

self.a ,self.b = self.b ,self.a+self.b # 计算下一个值

if self.a > 100: # 退出循环的条件

raise StopIteration();

return self.a # 返回下一值

for n in Fib():

print(n)

执行结果:

1

1

2

3

5

8

13

21

34

55

89

3. __getitem__

Fib 实例虽然能够作用于 for 循环,和 list 有点像,但是不能将它当成 list 使用。比如取第3个元素:

>>> Fib()[3]

Traceback (most recent call last):

File "", line 1, in TypeError: 'Fib' object does not support indexing

若要像list一样按照索引来获取元素,需要实现__getitem__()方法

>>> class Fib(object):

... def __getitem__(self,n):

... a = 0

... b = 1

... for x in range(n):

... a,b = b , a+b

... return a

...

>>>

>>> fib = Fib()

>>>

>>> fib[3]

2

>>>

>>> fib[5]

5

4. __getattr__

正常情况下,调用类的方法或属性时,如果类的方法或属性不存在就会报错。

定义Student类:

>>> class Student(object):

... def __init__(self):

... self.name = 'zth'

...

>>>

>>> s = Student()

>>>

>>> s.name

'zth'

>>>

>>> s.age

Traceback (most recent call last):

File "", line 1, in AttributeError: 'Student' object has no attribute 'age'

要避免这个错误,除了可以添加一个score属性外,Python还提供了另一种机制,就是写一个__getattr__()方法,动态返回一个属性。

>>> class Student:

... def __init__(self):

... self.name = 'zth'

... def __getattr__(self,attr):

... if attr == 'age':

... return 20

...

>>>

>>> s = Student()

>>>

>>> s.name

'zth'

>>> s.age

20

注意,只有在没有找到属性的情况下才调用__getattr__,已有的属性(如name),不会在__getattr__中查找。此外,如果所有调用都会返回None(如stu.abc),就是定义的__getattr__,返回None。

5. __call__

一个对象实例可以有自己的属性和方法,调用实例的方法时使用  instance.method()  调用。能不能直接在实例本身调用,答案是可以的。

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

>>> class Student:

... def __init__(self,name):

... self.name = name

... def __call__(self):

... print('姓名:%s'%self.name)

...

>>>

>>> s = Student('zth')

>>>

>>> s()

姓名:zth

__call__() 还可以定义参数。对实例进行直接调用就像对一个函数调用一样,完全可以把对象看成函数,把函数看成对象,因为这两者本来就是有根本的区别。

如果把对象看成函数,函数本身就可以在运行期间动态创建出来,因为类的实例都是运行期间创建出来的。

怎判断一个变量是对象还是函数呢?

很多时候判断一个对象能否被调用,可以使用Callable()函数,比如函数和上面定义带有__call__()的类实例。

>>> callable(Student('zth'))

True

>>>

>>> callable(max)

True

>>>

>>> callable([1,3,5])

False

>>>

>>> callable(None)

False

6.  getattr():

getattr( ) 函数用于返回一个对象指定的属性值。如果指定的属性不存在,则返回default的值,若没有设置default参数,则抛出AttributeError异常。以下为该函数的语法:

getattr(object, name[, default])

object -- 对象

name -- 字符串,对象属性。

default -- 默认返回值,如果不提供该参数,在没有对应属性时,将触发 AttributeError。

返回值:返回对象属性值。

>>> class People:

... name = 'zth'

... age = 20

...

>>>

>>> a= People()

>>>

>>>

>>> getattr( a ,'name')

'zth'

>>>

>>> getattr( a ,'class',5)

5

>>>

>>> getattr( a ,'class')

Traceback (most recent call last):

File "", line 1, in AttributeError: 'People' object has no attribute 'class'

7 . setattr()

setattr( )函数对应函数getatt(),用于设置指定属性的值,若指定的属性不存在则新建属性并赋值。以下为该函数的语法:

setattr(object, name, value)

object -- 对象。

name -- 字符串,对象属性。

value -- 属性值。

返回值:无

>>> class People:

... name = 'zth'

...

>>>

>>>

>>> a = People()

>>>

>>> setattr(a, 'name','en')

>>>

>>> setattr(a, 'age','20')

>>>

>>> getattr(a,'name')

'en'

>>>

>>> a.age

'20'

8.  delattr()

delattr( )函数用于删除属性,若属性不存在则抛出 AttributeError 异常。以下为该函数的语法:

delattr(object, name)

object -- 类名。

name -- 必须是对象的属性。

返回值:无

delattr(x, 'foobar') 相等于 del x.foobar。

>>> class People:

... name = 'zth'

... age = 20

...

>>>

>>> s = People()

>>>

>>> s.name

'zth'

>>>

>>>

>>> delattr(People, 'name')

>>>

>>> s.name

Traceback (most recent call last):

File "", line 1, in AttributeError: 'People' object has no attribute 'name'

>>>

>>> del People.age

>>>

>>> s.age

Traceback (most recent call last):

File "", line 1, in AttributeError: 'People' object has no attribute 'age'

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值