mirror of https://github.com/TwoWater/Python
两点水
parent
fdbf518c1e
commit
1b69364df2
|
@ -67,7 +67,7 @@
|
||||||
- [使用 `type()` 动态创建类](/python12/2.md)
|
- [使用 `type()` 动态创建类](/python12/2.md)
|
||||||
- [什么是元类](/python12/3.md)
|
- [什么是元类](/python12/3.md)
|
||||||
- [自定义元类](/python12/4.md)
|
- [自定义元类](/python12/4.md)
|
||||||
- [使用元类](/python12/4.md)
|
- [使用元类](/python12/5.md)
|
||||||
* [线程与进程](/python13/Preface.md)
|
* [线程与进程](/python13/Preface.md)
|
||||||
- [线程与进程](/python13/1.md)
|
- [线程与进程](/python13/1.md)
|
||||||
- [多线程编程](/python13/2.md)
|
- [多线程编程](/python13/2.md)
|
||||||
|
|
|
@ -22,6 +22,6 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
输出的结果:
|
输出的结果:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
可以看到,一个类的魔术方法还是挺多的,截图也没有截全,不过我们只需要了解一些常见和常用的魔术方法就好了。
|
可以看到,一个类的魔术方法还是挺多的,截图也没有截全,不过我们只需要了解一些常见和常用的魔术方法就好了。
|
||||||
|
|
|
@ -16,7 +16,7 @@ user=User('两点水',23)
|
||||||
|
|
||||||
实际上,创建一个类的过程是分为两步的,一步是创建类的对象,还有一步就是对类进行初始化。`__new__` 是用来创建类并返回这个类的实例, 而`__init__` 只是将传入的参数来初始化该实例.`__new__` 在创建一个实例的过程中必定会被调用,但 `__init__` 就不一定,比如通过pickle.load 的方式反序列化一个实例时就不会调用 `__init__` 方法。
|
实际上,创建一个类的过程是分为两步的,一步是创建类的对象,还有一步就是对类进行初始化。`__new__` 是用来创建类并返回这个类的实例, 而`__init__` 只是将传入的参数来初始化该实例.`__new__` 在创建一个实例的过程中必定会被调用,但 `__init__` 就不一定,比如通过pickle.load 的方式反序列化一个实例时就不会调用 `__init__` 方法。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
`def __new__(cls)` 是在 `def __init__(self)` 方法之前调用的,作用是返回一个实例对象。还有一点需要注意的是:`__new__` 方法总是需要返回该类的一个实例,而 `__init__` 不能返回除了 `None` 的任何值
|
`def __new__(cls)` 是在 `def __init__(self)` 方法之前调用的,作用是返回一个实例对象。还有一点需要注意的是:`__new__` 方法总是需要返回该类的一个实例,而 `__init__` 不能返回除了 `None` 的任何值
|
||||||
|
|
||||||
|
|
|
@ -109,4 +109,4 @@ num1 >= num2 ? --------> False
|
||||||
|
|
||||||
最后,如果对本文感兴趣的,可以关注下公众号:
|
最后,如果对本文感兴趣的,可以关注下公众号:
|
||||||
|
|
||||||

|

|
||||||
|
|
|
@ -4,4 +4,4 @@
|
||||||
|
|
||||||
# 目录 #
|
# 目录 #
|
||||||
|
|
||||||

|

|
||||||
|
|
|
@ -37,6 +37,6 @@ print('\n', Month.Jan)
|
||||||
输出的结果如下:
|
输出的结果如下:
|
||||||
|
|
||||||
|
|
||||||

|

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

|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,4 +6,4 @@
|
||||||
|
|
||||||
# 目录 #
|
# 目录 #
|
||||||
|
|
||||||

|

|
||||||
|
|
|
@ -30,4 +30,4 @@ Python 中的一切都是对象,它们要么是类的实例,要么是元类
|
||||||
|
|
||||||
最后如果对本文有兴趣,可以关注公众号:
|
最后如果对本文有兴趣,可以关注公众号:
|
||||||
|
|
||||||

|

|
||||||
|
|
|
@ -4,4 +4,4 @@
|
||||||
|
|
||||||
# 目录 #
|
# 目录 #
|
||||||
|
|
||||||

|

|
||||||
|
|
|
@ -182,7 +182,7 @@ r_lock = threading.RLock()
|
||||||
|
|
||||||
其中条件变量可以看成不同的线程先后 acquire 获得锁,如果不满足条件,可以理解为被扔到一个( Lock 或 RLock )的 waiting 池。直达其他线程 notify 之后再重新判断条件。不断的重复这一过程,从而解决复杂的同步问题。
|
其中条件变量可以看成不同的线程先后 acquire 获得锁,如果不满足条件,可以理解为被扔到一个( Lock 或 RLock )的 waiting 池。直达其他线程 notify 之后再重新判断条件。不断的重复这一过程,从而解决复杂的同步问题。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
该模式常用于生产者消费者模式,具体看看下面在线购物买家和卖家的示例:
|
该模式常用于生产者消费者模式,具体看看下面在线购物买家和卖家的示例:
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
输出的结果:
|
输出的结果:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## 2、把进程创建成类 ##
|
## 2、把进程创建成类 ##
|
||||||
|
@ -83,8 +83,7 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
输出结果如下:
|
输出结果如下:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## 3、daemon 属性 ##
|
## 3、daemon 属性 ##
|
||||||
|
|
||||||
|
@ -310,4 +309,3 @@ if __name__ == '__main__':
|
||||||
写进 Queue 的值为:四点水
|
写进 Queue 的值为:四点水
|
||||||
从 Queue 读取的值为:四点水
|
从 Queue 读取的值为:四点水
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -4,4 +4,4 @@
|
||||||
|
|
||||||
# 目录 #
|
# 目录 #
|
||||||
|
|
||||||

|

|
||||||
|
|
|
@ -16,6 +16,6 @@
|
||||||
|
|
||||||
Python 本身就内置了很多非常有用的模块,只要安装完毕,这些模块就可以立刻使用。我们可以尝试找下这些模块,比如我的 Python 安装目录是默认的安装目录,在 C:\Users\Administrator\AppData\Local\Programs\Python\Python36 ,然后找到 Lib 目录,就可以发现里面全部都是模块,没错,这些 `.py` 文件就是模块了。
|
Python 本身就内置了很多非常有用的模块,只要安装完毕,这些模块就可以立刻使用。我们可以尝试找下这些模块,比如我的 Python 安装目录是默认的安装目录,在 C:\Users\Administrator\AppData\Local\Programs\Python\Python36 ,然后找到 Lib 目录,就可以发现里面全部都是模块,没错,这些 `.py` 文件就是模块了。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
其实模块可以分为标准库模块和自定义模块,而刚刚我们看到的 Lib 目录下的都是标准库模块。
|
其实模块可以分为标准库模块和自定义模块,而刚刚我们看到的 Lib 目录下的都是标准库模块。
|
|
@ -73,11 +73,12 @@ from modname import name1[, name2[, ... nameN]]
|
||||||
|
|
||||||
`import` 导入 sys 模块,然后使用 version 属性
|
`import` 导入 sys 模块,然后使用 version 属性
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
`from···import` 直接导入 version 属性
|
`from···import` 直接导入 version 属性
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## 3、from ··· import * ##
|
## 3、from ··· import * ##
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,10 @@
|
||||||
|
|
||||||
首先创建了模块 lname ,然后判断一下是否是主模块,如果是主模块就输出 `main` 不是,就输出 `not main` ,首先直接运行该模块,由于该模块是直接使用,而没有被人调用,所以是主模块,因此输出了 `main` ,具体看下图:
|
首先创建了模块 lname ,然后判断一下是否是主模块,如果是主模块就输出 `main` 不是,就输出 `not main` ,首先直接运行该模块,由于该模块是直接使用,而没有被人调用,所以是主模块,因此输出了 `main` ,具体看下图:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
然后又创建一个 user_lname 模块,里面只是简单的导入了 lname 模块,然后执行,输出的结果是 `not main` ,因为 lname 模块被该模块调用了,所以不是主模块,输出结果如图:
|
然后又创建一个 user_lname 模块,里面只是简单的导入了 lname 模块,然后执行,输出的结果是 `not main` ,因为 lname 模块被该模块调用了,所以不是主模块,输出结果如图:
|
||||||
|
|
||||||

|
|
||||||
|

|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
比如最开始的例子,就引入了包,这样子做就算有相同的模块名,也不会造成重复,因为包名不同,其实也就是路径不同。如下图,引入了包名后, lname.py 其实变成了 com.Learn.module.nameattributes.lname
|
比如最开始的例子,就引入了包,这样子做就算有相同的模块名,也不会造成重复,因为包名不同,其实也就是路径不同。如下图,引入了包名后, lname.py 其实变成了 com.Learn.module.nameattributes.lname
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
仔细观察的人,基本会发现,每一个包目录下面都会有一个 `__init__.py` 的文件,为什么呢?
|
仔细观察的人,基本会发现,每一个包目录下面都会有一个 `__init__.py` 的文件,为什么呢?
|
||||||
|
|
||||||
|
|
|
@ -4,4 +4,4 @@
|
||||||
|
|
||||||
# 目录 #
|
# 目录 #
|
||||||
|
|
||||||

|

|
||||||
|
|
|
@ -52,7 +52,7 @@ t.prt()
|
||||||
|
|
||||||
观察输出的结果:
|
观察输出的结果:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
从执行结果可以很明显的看出,self 代表的是类的实例,输出的是当前对象的地址,而 `self.__class__` 则指向类。
|
从执行结果可以很明显的看出,self 代表的是类的实例,输出的是当前对象的地址,而 `self.__class__` 则指向类。
|
||||||
|
|
||||||
|
@ -115,4 +115,3 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
|
|
||||||
仔细观察输出的结果,对比一下,就能观察出来,注意喔,Pyhton3 中输出的结果是一模一样的,因为Python3 中没有新式类旧式类的问题。
|
仔细观察输出的结果,对比一下,就能观察出来,注意喔,Pyhton3 中输出的结果是一模一样的,因为Python3 中没有新式类旧式类的问题。
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ class UserInfo(object):
|
||||||
|
|
||||||
为什么只能说一般情况下呢?因为实际上, Python 中是没有提供私有属性等功能的。但是 Python 对属性的访问控制是靠程序员自觉的。为什么这么说呢?看看下面的示例:
|
为什么只能说一般情况下呢?因为实际上, Python 中是没有提供私有属性等功能的。但是 Python 对属性的访问控制是靠程序员自觉的。为什么这么说呢?看看下面的示例:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
仔细看图片,为什么说双下划线不是真正的私有属性呢?我们看下下面的例子,用下面的例子来验证:
|
仔细看图片,为什么说双下划线不是真正的私有属性呢?我们看下下面的例子,用下面的例子来验证:
|
||||||
|
|
||||||
|
@ -61,4 +61,4 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
输出的结果如下图:
|
输出的结果如下图:
|
||||||
|
|
||||||

|

|
||||||
|
|
|
@ -103,4 +103,4 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
运行的结果:
|
运行的结果:
|
||||||
|
|
||||||

|

|
||||||
|
|
|
@ -112,7 +112,7 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
最后打印的结果:
|
最后打印的结果:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
这里就是重写了父类的构造函数。
|
这里就是重写了父类的构造函数。
|
||||||
|
|
||||||
|
|
|
@ -7,4 +7,4 @@
|
||||||
|
|
||||||
# 目录 #
|
# 目录 #
|
||||||
|
|
||||||

|

|
||||||
|
|
Loading…
Reference in New Issue