Python部分默认函数

1. __init__

Python在你实例化class类的时候会检查这个类中是否有init,如果有就会调用它。进行初始化。init()方法意义重大的原因有两个:

  1. 在对象生命周期中初始化;每个对象必须正确初始化后才能正常工作。
  2. _init__()参数值可以有多种形式。

因为有很多种方式为init()提供参数值,对于对象创建有大量的用例,我们可以看看其中的几个。我们想尽可能的弄清楚,因此我们需要定义一个初始化来正确的描述问题区域。

2. __name__

name 是属于 python 中的内置类属性,就是它会天生就存在于一个 python 程序中,代表对应程序名称。

比如所示的一段代码里面(这个脚本命名为 pcRequests.py),我只设了一个函数,但是并没有地方运行它,所以当 run 了这一段代码之后我们有会发现这个函数并没有被调用。但是当我们在运行这个代码时这个代码的 name 的值为 main (一段程序作为主线运行程序时其内置名称就是 main)。

结果:

当这个 pcRequests.py 作为模块被调用时,则它的 name 就是它自己的名字:

import pcRequestspcRequestsc=pcRequestsc.__name__

结果:

'pcRequests'

看到这里应该能明白,自己的 name 在自己用时就是 main,当自己作为模块被调用时就是自己的名字,就相当于:我管自己叫我自己,但是在朋友眼里我就是小仙女一样。

3. __new__

  1. new方法默认返回实例对象供init方法、实例方法使用。
  2. init方法为初始化方法,为类的实例提供一些属性或完成一些动作。
  3. new方法创建实例对象供init方法使用,init方法定制实例对象。
    new方法必须返回值,init方法不需要返回值。(如果返回非None值就报错)
  4. 对象的创建和初始化过程示意图
  5. 执行流程:
    1. 创建Person类的对象student=Person(‘kb’,19),先执行等号右边的内容Person(‘kb’,19)
    2. 调用Person类中的new方法,并将Person类传给方法中的cls
    3. 创建obj对象
    4. 执行init方法,并将obj对象赋值给self
    5. 将self再传给student1对象
  6. 我们比较两个方法的参数,可以发现new方法是传入类(cls),而init方法传入类的实例化对象(self),而有意思的是,new方法返回的值就是一个实例化对象(ps:如果new方法返回None,则init方法不会被执行,并且返回值只能调用父类中的new方法,而不能调用毫无关系的类的new方法)。

我们可以这么理解它们之间的关系,new是开辟疆域的大将军,而init是在这片疆域上辛勤劳作的小老百姓,只有new执行完后,开辟好疆域后,init才能工作,结合到代码,也就是new的返回值正是init中self。

4. __call__

4.1. 使用示例

例类Run中展示call的使用方法,call接收对象传入的参数,可在call方法里执行某一特定对象的参数和方法(pytorch中模型正向传播的forward应该是对该函数的重写):

输出:

对象实例w的两种等价调用方式分别是Run.call(x)和Run(x),前者为普通的调用类方法的方式,后者为Python中的语法实现了将对象变为可调用的目的。

4.2. 类可调用的与对象可调用的不同

要注意类都是可调用的,而对象可通过call()函数来设计为可调用或者不可调用。如下代码

这里Apple类没有定义call()方法,因此其对象实例不是可调用对象,但是类本身是可调用的,因为调用类实际上就是返回一个实例,类似于执行init()函数。

4.3. call()函数还有其它用途

Python可以进行元编程。有一个技巧就是,当你不想让用户能够实例化一个类,而只能使用类的静态方法的时候,你可以通过结合call()函数与元编程来实现:

现在c = Cherry()会报错,而c = Cherry().about()可正常执行

5. __getitem__

例类Tag,自定义的对象如果没有迭代器 iternext 迭代器协议,使用[]运算符取对象列表或者字典中的值时,会自动调用它的 getitem 方法;可重定义此方法,使对象通过类似列表或者字典的调用方式实现迭代取值:

输出:

6. enterexit

为了支持with语句,可以在类中定义enterexit函数

输出:

赞赏

微信赞赏支付宝赞赏

发表评论

邮箱地址不会被公开。 必填项已用*标注