Skip to content

Commit d7a75da

Browse files
committed
所有基础文章修改完毕
1 parent 95ad977 commit d7a75da

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+387
-145
lines changed

Article/python10/1.md renamed to Article/PythonBasis/python10/1.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# 一、Python 的 Magic Method #
22

3-
在 Python 中,所有以 "__" 双下划线包起来的方法,都统称为"魔术方法"。比如我们接触最多的 `__init__` 。魔术方法有什么作用呢?
3+
在 Python 中,所有以 "__" 双下划线包起来的方法,都统称为"魔术方法"。比如我们接触最多的 `__init__`
4+
5+
魔术方法有什么作用呢?
46

57
使用这些魔术方法,我们可以构造出优美的代码,将复杂的逻辑封装成简单的方法。
68

@@ -22,6 +24,10 @@ if __name__ == '__main__':
2224

2325
输出的结果:
2426

25-
![Python 类的魔术方法](http://p1ceh5usj.bkt.clouddn.com/Python%20%E7%B1%BB%E7%9A%84%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95.png)
27+
```
28+
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
29+
```
30+
31+
可以看到,一个类的魔术方法还是挺多的,不过我们只需要了解一些常见和常用的魔术方法就好了。
32+
2633

27-
可以看到,一个类的魔术方法还是挺多的,截图也没有截全,不过我们只需要了解一些常见和常用的魔术方法就好了。

Article/python10/2.md renamed to Article/PythonBasis/python10/2.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# 二、构造(`__new__`)和初始化(`__init__`) #
22

3-
通过上一篇的内容,我们已经知道定义一个类时,我们经常会通过 `__init__(self)` 的方法在实例化对象的时候,对属性进行设置。比如下面的例子:
3+
通过之前的学习,我们已经知道定义一个类时,我们经常会通过 `__init__(self)` 的方法在实例化对象的时候,对属性进行设置。
4+
5+
比如下面的例子:
46

57
```python
68
#!/usr/bin/env python3
@@ -14,9 +16,11 @@ class User(object):
1416
user=User('两点水',23)
1517
```
1618

17-
实际上,创建一个类的过程是分为两步的,一步是创建类的对象,还有一步就是对类进行初始化。`__new__` 是用来创建类并返回这个类的实例, 而`__init__` 只是将传入的参数来初始化该实例.`__new__` 在创建一个实例的过程中必定会被调用,但 `__init__` 就不一定,比如通过pickle.load 的方式反序列化一个实例时就不会调用 `__init__` 方法。
19+
实际上,创建一个类的过程是分为两步的,一步是创建类的对象,还有一步就是对类进行初始化。
20+
21+
`__new__` 是用来创建类并返回这个类的实例, 而`__init__` 只是将传入的参数来初始化该实例.`__new__` 在创建一个实例的过程中必定会被调用,但 `__init__` 就不一定,比如通过 pickle.load 的方式反序列化一个实例时就不会调用 `__init__` 方法。
1822

19-
![Python类创建的过程](http://upload-images.jianshu.io/upload_images/2136918-a2b39b078cc81841?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
23+
![](http://twowaterimage.oss-cn-beijing.aliyuncs.com/2019-10-14-Python%E7%B1%BB%E5%88%9B%E5%BB%BA%E7%9A%84%E8%BF%87%E7%A8%8B.png)
2024

2125
`def __new__(cls)` 是在 `def __init__(self)` 方法之前调用的,作用是返回一个实例对象。还有一点需要注意的是:`__new__` 方法总是需要返回该类的一个实例,而 `__init__` 不能返回除了 `None` 的任何值
2226

@@ -57,3 +61,5 @@ if __name__ == '__main__':
5761
其实在实际开发中,很少会用到 `__new__` 方法,除非你希望能够控制类的创建。通常讲到 `__new__` ,都是牵扯到 `metaclass`(元类)的。
5862

5963
当然当一个对象的生命周期结束的时候,析构函数 `__del__` 方法会被调用。但是这个方法是 Python 自己对对象进行垃圾回收的。
64+
65+
File renamed without changes.

Article/python10/4.md renamed to Article/PythonBasis/python10/4.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
# 四、对象的描述器 #
22

3-
一般来说,一个描述器是一个有“绑定行为”的对象属性 (object attribute),它的访问控制被描述器协议方法重写。这些方法是 `__get__()`, `__set__()` , 和 `__delete__()` 。有这些方法的对象叫做描述器。
3+
一般来说,一个描述器是一个有“绑定行为”的对象属性 (object attribute),它的访问控制被描述器协议方法重写。
44

5-
默认对属性的访问控制是从对象的字典里面 (`__dict__`) 中获取 (get) , 设置 (set) 和删除 (delete) 。举例来说, `a.x` 的查找顺序是, `a.__dict__['x']` , 然后 `type(a).__dict__['x']` , 然后找 `type(a)` 的父类 ( 不包括元类 (metaclass) ).如果查找到的值是一个描述器, Python 就会调用描述器的方法来重写默认的控制行为。这个重写发生在这个查找环节的哪里取决于定义了哪个描述器方法。注意, 只有在新式类中时描述器才会起作用。在之前的篇节中已经提到新式类和旧式类的,有兴趣可以查看之前的篇节来看看,至于新式类最大的特点就是所有类都继承自 type 或者 object 的类
5+
这些方法是 `__get__()`, `__set__()` , `__delete__()`
66

7-
在面向对象编程时,如果一个类的属性有相互依赖的关系时,使用描述器来编写代码可以很巧妙的组织逻辑。在 Django 的 ORM 中,models.Model中的 InterField 等字段, 就是通过描述器来实现功能的。
7+
有这些方法的对象叫做描述器。
8+
9+
默认对属性的访问控制是从对象的字典里面 (`__dict__`) 中获取 (get) , 设置 (set) 和删除 (delete) 。
10+
11+
举例来说, `a.x` 的查找顺序是, `a.__dict__['x']` , 然后 `type(a).__dict__['x']` , 然后找 `type(a)` 的父类 ( 不包括元类 (metaclass) ).如果查找到的值是一个描述器, Python 就会调用描述器的方法来重写默认的控制行为。
12+
13+
这个重写发生在这个查找环节的哪里取决于定义了哪个描述器方法。
14+
15+
注意, 只有在新式类中时描述器才会起作用。在之前的篇节中已经提到新式类和旧式类的,有兴趣可以查看之前的篇节来看看,至于新式类最大的特点就是所有类都继承自 type 或者 object 的类。
16+
17+
在面向对象编程时,如果一个类的属性有相互依赖的关系时,使用描述器来编写代码可以很巧妙的组织逻辑。在 Django 的 ORM 中,models.Model 中的 InterField 等字段, 就是通过描述器来实现功能的。
818

919
我们先看下下面的例子:
1020

@@ -129,3 +139,5 @@ if __name__ == '__main__':
129139
我们只是修改了 meter ,并且将其赋值成为 int ,但 foot 也修改了。这是 `__set__` 发挥了作用.
130140

131141
描述器对象 (Meter、Foot) 不能独立存在, 它需要被另一个所有者类 (Distance) 所持有。描述器对象可以访问到其拥有者实例的属性,比如例子中 Foot 的 `instance.meter`
142+
143+

Article/python10/5.md renamed to Article/PythonBasis/python10/5.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
# 五、自定义容器(Container) #
22

3-
经过之前编章的介绍,我们知道在 Python 中,常见的容器类型有: dict, tuple, list, string。其中也提到过可容器和不可变容器的概念。其中 tuple, string 是不可变容器,dict, list 是可变容器。 可变容器和不可变容器的区别在于,不可变容器一旦赋值后,不可对其中的某个元素进行修改。当然具体的介绍,可以看回之前的文章,有图文介绍。
3+
经过之前编章的介绍,我们知道在 Python 中,常见的容器类型有: dict, tuple, list, string。其中也提到过可容器和不可变容器的概念。其中 tuple, string 是不可变容器,dict, list 是可变容器。
44

5-
那么这里先提出一个问题,这些数据结构就够我们开发使用吗?不够的时候,或者说有些特殊的需求不能单单只使用这些基本的容器解决的时候,该怎么办呢?
5+
可变容器和不可变容器的区别在于,不可变容器一旦赋值后,不可对其中的某个元素进行修改。当然具体的介绍,可以看回之前的文章,有图文介绍。
6+
7+
那么这里先提出一个问题,这些数据结构就够我们开发使用吗?
8+
9+
不够的时候,或者说有些特殊的需求不能单单只使用这些基本的容器解决的时候,该怎么办呢?
610

711
这个时候就需要自定义容器了,那么具体我们该怎么做呢?
812

@@ -78,3 +82,5 @@ class FunctionalList:
7882
return self.values[:n]
7983

8084
```
85+
86+

Article/python10/6.md renamed to Article/PythonBasis/python10/6.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ num1 >= num2 ? --------> False
107107
|`__xor__(self, other)`|实现了位操作 `^`|
108108

109109

110-
最后,如果对本文感兴趣的,可以关注下公众号:
110+
可以关注下公众号:
111+
112+
这个公号可能很少更新,但是一更新,就是把整理的一系列文章更新上去。
113+
114+
![](http://twowaterimage.oss-cn-beijing.aliyuncs.com/2019-10-14-WechatIMG697.jpeg)
115+
111116

112-
![公众号](http://twowater.com.cn/images/20171204192251900.gif)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# 前言 #
2+
3+
有时候修改文章,真的修改到想死。真的很耗时间,很烦的。
4+
5+
好吧,每次都是安慰自己,快完结了,快更新完了。
6+
7+
# 目录 #
8+
9+
![](http://twowaterimage.oss-cn-beijing.aliyuncs.com/2019-10-14-Python%20%E7%9A%84%20Magic%20Method.png)
10+
11+

Article/python11/1.md renamed to Article/PythonBasis/python11/1.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ DEC = 12
1515

1616
那有没有什么好的方法呢?
1717

18-
这时候我们定义一个 class 类型,每个常量都是 class 里面唯一的实例。正好 Python 提供了 Enum 类来实现这个功能如下:
18+
这时候我们定义一个 class 类型,每个常量都是 class 里面唯一的实例。
19+
20+
正好 Python 提供了 Enum 类来实现这个功能如下:
1921

2022
```python
2123
#!/usr/bin/env python3
@@ -37,6 +39,14 @@ print('\n', Month.Jan)
3739
输出的结果如下:
3840

3941

40-
![Python3 枚举类型的使用](http://p1ceh5usj.bkt.clouddn.com/Python3%20%E6%9E%9A%E4%B8%BE%E7%B1%BB%E5%9E%8B%E7%9A%84%E4%BD%BF%E7%94%A8.png)
42+
![](http://twowaterimage.oss-cn-beijing.aliyuncs.com/2019-10-14-Python3%20%E6%9E%9A%E4%B8%BE%E7%B1%BB%E5%9E%8B%E7%9A%84%E4%BD%BF%E7%94%A8.png)
43+
44+
我们使用 `Enum` 来定义了一个枚举类。
45+
46+
上面的代码,我们创建了一个有关月份的枚举类型 Month ,这里要注意的是构造参数,第一个参数 Month 表示的是该枚举类的类名,第二个 tuple 参数,表示的是枚举类的值;当然,枚举类通过 `__members__` 遍历它的所有成员的方法。
47+
48+
注意的一点是 , `member.value` 是自动赋给成员的 `int` 类型的常量,默认是从 1 开始的。
49+
50+
**而且 Enum 的成员均为单例(Singleton),并且不可实例化,不可更改**
51+
4152

42-
可见,我们可以直接使用 `Enum` 来定义一个枚举类。上面的代码,我们创建了一个有关月份的枚举类型 Month ,这里要注意的是构造参数,第一个参数 Month 表示的是该枚举类的类名,第二个 tuple 参数,表示的是枚举类的值;当然,枚举类通过 `__members__` 遍历它的所有成员的方法。注意的一点是 , `member.value` 是自动赋给成员的 `int`类型的常量,默认是从 1 开始的。而且 Enum 的成员均为单例(Singleton),并且不可实例化,不可更改

Article/python11/2.md renamed to Article/PythonBasis/python11/2.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
# 二、Enum 的源码 #
22

3-
通过上面的实例可以知道通过 `__members__` 可以遍历枚举类的所有成员。那为什么呢?
3+
通过上面的实例可以知道通过 `__members__` 可以遍历枚举类的所有成员。
44

5-
我们可以先来大致看看 Enum 的源码是如何实现的;Enum 在模块 enum.py 中,先来看看 Enum 类的片段
5+
那有没有想过为什么呢?
6+
7+
当你看到那段代码的时候,有没有想过为什么通过 `__members__` 就能遍历枚举类型的所有成员出来?
8+
9+
10+
我们可以先来大致看看 Enum 的源码是如何实现的;
11+
12+
Enum 在模块 enum.py 中,先来看看 Enum 类的片段
613

714
```python
815
class Enum(metaclass=EnumMeta):
@@ -25,4 +32,5 @@ class EnumMeta(type):
2532
return MappingProxyType(cls._member_map_)
2633
```
2734

28-
首先 `__members__` 方法返回的是一个包含一个 Dict 既 Map 的 MappingProxyType,并且通过 @property 将方法 `__members__(cls)` 的访问方式改变为了变量的的形式,既可以直接通过 `__members__` 来进行访问了
35+
首先 `__members__` 方法返回的是一个包含一个 Dict 既 Map 的 MappingProxyType,并且通过 @property 将方法 `__members__(cls)` 的访问方式改变为了变量的的形式,那么就可以直接通过 `__members__` 来进行访问了
36+

Article/python11/3.md renamed to Article/PythonBasis/python11/3.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@ if __name__ == '__main__':
3838

3939
输出的结果如下:
4040

41-
![Python3 自定义类型的枚举类](http://p1ceh5usj.bkt.clouddn.com/Python3%20%E8%87%AA%E5%AE%9A%E4%B9%89%E7%B1%BB%E5%9E%8B%E7%9A%84%E6%9E%9A%E4%B8%BE%E7%B1%BB.png)
41+
![](http://twowaterimage.oss-cn-beijing.aliyuncs.com/2019-10-14-Python3%20%E8%87%AA%E5%AE%9A%E4%B9%89%E7%B1%BB%E5%9E%8B%E7%9A%84%E6%9E%9A%E4%B8%BE%E7%B1%BB.png)
4242

4343

4444

4545
通过上面的例子,可以知道枚举模块定义了具有迭代 (interator) 和比较(comparison) 功能的枚举类型。 它可以用来为值创建明确定义的符号,而不是使用具体的整数或字符串。
46+
47+

0 commit comments

Comments
 (0)