diff --git a/PythonLanguage/14. 魔法方法.md b/PythonLanguage/14. 魔法方法.md index dd09ce5..64b5658 100644 --- a/PythonLanguage/14. 魔法方法.md +++ b/PythonLanguage/14. 魔法方法.md @@ -13,8 +13,7 @@ --- ## 1. 基本的魔法方法 -`__init__(self[, ...])` -- 构造器,当一个实例被创建的时候调用的初始化方法 +- `__init__(self[, ...])` 构造器,当一个实例被创建的时候调用的初始化方法 【例子】 ```python @@ -36,10 +35,9 @@ print(rect.getArea()) # 20 ``` -`__new__(cls[, ...])` -- `__new__`是在一个对象实例化的时候所调用的第一个方法,在调用`__init__`初始化前,先调用`__new__`。 -- `__new__`至少要有一个参数`cls`,代表要实例化的类,此参数在实例化时由 Python 解释器自动提供,后面的参数直接传递给`__init__`。 -- `__new__`对当前类进行了实例化,并将实例返回,传给`__init__`的`self`。但是,执行了`__new__`,并不一定会进入`__init__`,只有`__new__`返回了,当前类`cls`的实例,当前类的`__init__`才会进入。 +- `__new__(cls[, ...])` 在一个对象实例化的时候所调用的第一个方法,在调用`__init__`初始化前,先调用`__new__`。 + - `__new__`至少要有一个参数`cls`,代表要实例化的类,此参数在实例化时由 Python 解释器自动提供,后面的参数直接传递给`__init__`。 + - `__new__`对当前类进行了实例化,并将实例返回,传给`__init__`的`self`。但是,执行了`__new__`,并不一定会进入`__init__`,只有`__new__`返回了,当前类`cls`的实例,当前类的`__init__`才会进入。 【例子】 ```python @@ -106,9 +104,8 @@ b = B(10) ``` - 若`__new__`没有正确返回当前类`cls`的实例,那`__init__`是不会被调用的,即使是父类的实例也不行,将没有`__init__`被调用。 -- 可利用`__new__`实现单例模式。 -【例子】 +【例子】利用`__new__`实现单例模式。 ```python class Earth: pass @@ -150,9 +147,7 @@ a = CapStr("i love lsgogroup") print(a) # I LOVE LSGOGROUP ``` -`__del__(self)` - -析构器,当一个对象将要被系统回收之时调用的方法。 +- `__del__(self)` 析构器,当一个对象将要被系统回收之时调用的方法。 > Python 采用自动引用计数(ARC)方式来回收对象所占用的空间,当程序中有一个变量引用该 Python 对象时,Python 会自动保证该对象引用计数为 1;当程序中有两个变量引用该 Python 对象时,Python 会自动保证该对象引用计数为 2,依此类推,如果一个对象的引用计数变成了 0,则说明程序中不再有变量引用该对象,表明程序不再需要该对象,因此 Python 就会回收该对象。 > @@ -178,18 +173,18 @@ del c1 # into C __del__ ``` -`__str__` 和 `__repr__` -`__str__(self)`: -- 当你打印一个对象的时候,触发`__str__` -- 当你使用`%s`格式化的时候,触发`__str__` -- `str`强转数据类型的时候,触发`__str__` -`__repr__(self):` -- `repr`是`str`的备胎 -- 有`__str__`的时候执行`__str__`,没有实现`__str__`的时候,执行`__repr__` -- `repr(obj)`内置函数对应的结果是`__repr__`的返回值 -- 当你使用`%r`格式化的时候 触发`__repr__` +- `__str__(self)`: + - 当你打印一个对象的时候,触发`__str__` + - 当你使用`%s`格式化的时候,触发`__str__` + - `str`强转数据类型的时候,触发`__str__` + +- `__repr__(self)`: + - `repr`是`str`的备胎 + - 有`__str__`的时候执行`__str__`,没有实现`__str__`的时候,执行`__repr__` + - `repr(obj)`内置函数对应的结果是`__repr__`的返回值 + - 当你使用`%r`格式化的时候 触发`__repr__` 【例子】 ```python @@ -245,10 +240,13 @@ print('%r' %today) # datetime.date(2019, 10, 11) + + + --- ## 2. 算术运算符 -类型工厂函数,指的是不通过类而是通过函数来创建对象。 +类型工厂函数,指的是“不通过类而是通过函数来创建对象”。 【例子】 ```python @@ -271,6 +269,8 @@ print(list((1, 2, 3))) # [1, 2, 3] - `__add__(self, other)`定义加法的行为:`+` - `__sub__(self, other)`定义减法的行为:`-` +【例子】 + ```python class MyClass: @@ -386,6 +386,7 @@ print(1 + b) # -2 - `__ixor__(self, other)`定义赋值按位异或操作的行为:`^=` - `__ior__(self, other)`定义赋值按位或操作的行为:`|=` + --- ## 5. 一元运算符 - `__neg__(self)`定义正号的行为:`+x` @@ -393,18 +394,14 @@ print(1 + b) # -2 - `__abs__(self)`定义当被`abs()`调用时的行为 - `__invert__(self)`定义按位求反的行为:`~x` + --- ## 6. 属性访问 -`__getattr__`,`__getattribute__`,`__setattr__`和`__delattr__` - -`__getattr__(self, name)`: 定义当用户试图获取一个不存在的属性时的行为。 - -`__getattribute__(self, name)`:定义当该类的属性被访问时的行为(先调用该方法,查看是否存在该属性,若不存在,接着去调用`__getattr__`)。 - -`__setattr__(self, name, value)`:定义当一个属性被设置时的行为。 - -`__delattr__(self, name)`:定义当一个属性被删除时的行为。 +- `__getattr__(self, name)`: 定义当用户试图获取一个不存在的属性时的行为。 +- `__getattribute__(self, name)`:定义当该类的属性被访问时的行为(先调用该方法,查看是否存在该属性,若不存在,接着去调用`__getattr__`)。 +- `__setattr__(self, name, value)`:定义当一个属性被设置时的行为。 +- `__delattr__(self, name)`:定义当一个属性被删除时的行为。 【例子】 ```python @@ -437,6 +434,7 @@ del c.x # __delattr__ ``` + 扩展参考: - [技术图文:Python魔法方法之属性访问详解](https://mp.weixin.qq.com/s?__biz=MzIyNDA1NjA1NQ==&mid=2651011398&idx=1&sn=412562db40c2c4efacc3d75b64990a8f&chksm=f3e35edec494d7c8b3baffdc2806332ea358030d7c55cc9df27da19e5cae7c51917beb057dfd&token=523711417&lang=zh_CN#rd) @@ -741,6 +739,7 @@ for each in libs(100): - https://www.cnblogs.com/Jimmy1988/p/6804095.html - https://blog.csdn.net/johnsonguo/article/details/585193 + --- **练习题**: