Python基础——面向对象(@property、定制类)

添加属性和方法

正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性。
在这里插入图片描述
还可以尝试给实例绑定一个方法:
在这里插入图片描述
但是,给一个实例绑定的方法,对另一个实例是不起作用的,会报错:
在这里插入图片描述
通常情况下,上面的setAge方法可以直接定义在class中,但动态绑定允许我们在程序运行的过程中动态给class加上功能,这在静态语言中很难实现。

使用@property

装饰器(decorator)可以给函数动态加上功能。对于类的方法,装饰器一样起作用。Python内置的@property装饰器就是负责把一个方法变成属性调用的,我们在对实例属性操作的时候,就知道该属性很可能不是直接暴露的,而是通过getter和setter方法来实现的。还可以定义只读属性,只定义getter方法,不定义setter方法就是一个只读属性:

上面的birth是可读写属性,而age就是一个只读属性
@property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性。

定制类

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

定制__slots__

如果我们想要限制实例的属性怎么办?比如,只允许对Student实例添加name和age属性。
为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性:
在这里插入图片描述
使用__slots__要注意,slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的,除非在子类中也定义__slots,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。

定制__str__

我们先定义一个Student类,打印一个实例:
在这里插入图片描述
打印出一堆<main.Student object at 0x000017BB6D60D68,不好看。
因此我们定义__str__方法
在这里插入图片描述
直接敲变量不用print,打印出来的实例还是和之前一样
在这里插入图片描述
因为直接显示变量调用的不是__str__(),而是__repr__(),两者的区别是__str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串。
解决方法是再定义一个__repr__()。在Python中,函数名也可以是变量,因此可以偷懒:
在这里插入图片描述

定制__iter__

如果一个类想被用于for … in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的__next__()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。
我们以斐波那契数列为例,写一个Fib类,可以作用于for循环:
在这里插入图片描述

定制__call__

任何类,只需要定义一个__call__()方法,就可以直接对实例进行调用。
在这里插入图片描述
.call()还可以定义参数。对实例进行直接调用就好比对一个函数进行调用一样,所以你完全可以把对象看成函数,把函数看成对象,因为这两者之间本来就没啥根本的区别。
如果你把对象看成函数,那么函数本身其实也可以在运行期动态创建出来,因为类的实例都是运行期创建出来的,这么一来,我们就模糊了对象和函数的界限。
通过callable()函数,我们就可以判断一个对象是否是“可调用”对象。
在这里插入图片描述
Python的class允许定义许多定制方法,可以让我们非常方便地生成特定的类。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值