博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python — magic method
阅读量:5099 次
发布时间:2019-06-13

本文共 4387 字,大约阅读时间需要 14 分钟。

Python 中内置的特定的方法, 这些方法在进行特定的操作时,会自动被调用。

__init__(self, [ ])  # 类的构造函数, 用于初始化实例变量 不允许做任何形式的return

__new__(cls, [ ]) # 类的内置方法  对象实例化过程中第一个被调用的方法

  由于__init__()方法不能够返回一个非None的值,因此在实例化对象时不能够通过该方法对不可变对象(str、tuple)进行改变,此使可以重写__new__()方法,在__new__()方法中对不可变对象进行处理,返回需要的结果。

(构造方法__init__() 与 __new__())

1 class A(str): 2     def __init__(self, string): 3         super().__init__() 4         # 在 __init__()中 即使对 string 进行操作也不能够返回一个有效的值 5  6     def __new__(cls,string): 7         string = string.upper() 8         return str.__new__(cls, string) 9         #能够返回值10     11 a = A('yi jing beng pan le ')12 print(a)13 14 ###################################315 YI JING BENG PAN LE

__del__(self)       # 当对象的引用为 0 时调用 该方法, 并不是del 时调用该方法 (析构方法)

  示例代码如下,这是在IDLE中运行的结果,但是在jupyter notebook中运行的结果并不相同 在第二次实例化对象时仍然调用了 该方法。。。。。。。。。。

1 >>> class A(): 2     def __init__(self): 3         print('nothing') 4     def __del__(self): 5         print('del BIF 被调用了') 6  7          8 >>> a = A() 9 nothing10 >>> b = a11 >>> del a12 >>> del b13 del BIF 被调用了14 >>>

工厂函数:

  工厂函数即是类对象,在调用该函数时会生成一个实例对象。

 

算术运算的 内置方法。对象可以进行算术运算,可通过修改这些方法,改变对象的行为

  重写__add__()方法,要避免在算术运算方法中加入算术运算方法,避免出现无限递归的调用

 

1 >>> class new_int(int):2     def __add__(self, x):3         return int.__sub__(self, x)4 5     6 >>> a = new_int(10)7 >>> b = new_int(12)8 >>> a + b9 -2

以下两种方式的区别:在try_int(第8行)定义的__add__()方法中使用 int()工厂函数进行了类型转换,由于工厂函数即是类对象的实例化,因此int(self)相当于重新实例化一个对象,进行加法操作,此时不会再调用c或d的__add__()方法。因此不会出现递归调用。

1 >>> class new_int(int): 2     def __add__(self, x): 3         return self + x 4  5      6 >>> class try_int(int): 7     def __add__(self, x): 8         return int(self) + int(x) 9 10     11 >>> a = new_int(10)12 >>> b = new_int(10)13 >>> a + b14 Traceback (most recent call last):15   File "
", line 1, in
16 a + b17 File "
", line 3, in __add__18 return self + x19 File "
", line 3, in __add__20 return self + x21 File "
", line 3, in __add__22 return self + x23 [Previous line repeated 991 more times]24 RecursionError: maximum recursion depth exceeded25 >>> c = try_int(10)26 >>> d = try_int(10)27 >>> c + d28 2029 >>>

 

反运算符的变量顺序。

 

__str__() 与 __repr__()方法:

  __str__():当需要打印输出对象时(print(object)),调用的方法。__repr__()直接输入对象名称返回值。

 

1 class test(): 2     def start(self): 3         self.start = 10 4          5 t = test() 6 t.start() 7 t.start() 8  9 ######################################10 ---------------------------------------------------------------------------11 TypeError                                 Traceback (most recent call last)12 
in
13 5 t = test()14 6 t.start()15 ----> 7 t.start()16 17 TypeError: 'int' object is not callable

 

再一次强调,属性名与方法名重复会发生覆盖现象。请注意只有第七行报错:TypeError,原因时再第六行执行代码后会产生 第三行的同名变量,而后定义的变量会覆盖方法。

 

 

定义一个定时器的类,并通过重载其内部方法实现,定时器开始,结束,结果显示,及定时器对象的 加 (+,将两个定时器的时间相加并显示)操作。

  需要注意,三个类方法在实例化后的调用顺序,如在start() 调用之前调用 stop()、未调用stop()而调用 + 操作,通过实例变量 message,对当前操作进度进行记录,并通过对时间的判断进行错误提醒,有点类似于状态机的状态码。

# 通过重定义内置方法 定制类import datetimeclass Mytimer():    num = 0        def __init__(self):        self.__class__.num += 1        self.start_time = 0        self.stop_time = 0        self.time_sec = 0        self.message = '未开始计时!'        # 重定义 __str__ 以及 __repr__内置函数 用于控制输出    def __str__(self):        return self.message        __repr__ = __str__        def __add__(self, time):        if self.time_sec and time.time_sec:            add_result = self.time_sec + time.time_sec            self.message = '总共计时时间为:' + str(add_result)        else:            self.message = '计时未结束!'        return self.message        def start(self):        self.start_time = datetime.datetime.now()        print('计时开始!')        self.message = '未结束计时!'        def stop(self):        if self.start_time:            self.stop_time = datetime.datetime.now()            delta_time = self.stop_time - self.start_time            self.time_sec = delta_time.total_seconds()            self.message = '计时结果为:' + str(self.time_sec) +'S'            print('计时结束!')        else:            print('Plz run start first!')t = Mytimer()t1 = Mytimer()

定义类方法时需要注意实例变量与 函数的局部变量的区别,由于函数的局部变量生存空间仅限于该函数内部,因此需要在函数之间调用的变量需要设置未实例变量。实例变量与类变量之间由于作用对象不同,相互没有影响,类变量用于描述这个抽象类的属性,而实例变量用于描述实例化对象的属性。注意实例变量名与方法名不能相同,否则在__init__()初始化后会导致与变量名相同的函数被覆盖。

 

转载于:https://www.cnblogs.com/JYNNO1/p/10440313.html

你可能感兴趣的文章
我已下定决心,回郴州老家发展
查看>>
luoguP1402 酒店之王(网络流)
查看>>
PHP session回收机制
查看>>
Oracle存储过程生成日期维度
查看>>
crawler4j详细配置
查看>>
hql得到一个实体的数量
查看>>
BFC
查看>>
多线程排序
查看>>
jquery学习总结12-24
查看>>
干系人的管理
查看>>
iOS 支付宝的集成与遇到的问题
查看>>
iOS--Mesonry源码解析
查看>>
云计算分层
查看>>
Excel VBA记录
查看>>
Jmeter之Badboy录制脚本及简化脚本http请求(三)(转载)
查看>>
C#中动态加载和卸载DLL
查看>>
Dungelot游戏思考
查看>>
Spring AOP 切面学习随笔
查看>>
DOS 根据用户输入执行指令判断IF
查看>>
keytool导入导出多条目对比【原】
查看>>