避免竞态条件:Python中list、set、dict的线程安全策略

一、什么是模块

为了编写可维护的代码,把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,编程语言采用这种组织方式。在python中,一个.py文件就称之为一个模块。

二、使用模块有什么好处

  • 最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。经常引用其他模块,包括Python内置的模块和来自第三方的模块
  • 使用模块还可以避免函数名和变量名冲突。每个模块有独立的命名空间

三、模块分类

  • 内置标准模块(又称标准库)执行help(‘modules’)查看所有python自带模块列表
  • 第三方开源模块,可通过pip install 模块名联网安装
  • 自定义模块

四、模块调用

import module

from module import xx

from module.xx.xx import xx as rename

from module.xx.xx import *

注意:模块一旦被调用,即相当于执行了另外一个py文件里的代码

自定义模块

这个最简单, 创建一个.py文件,就可以称之为模块,就可以在另外一个程序里导入

模块查找路径

发现,自己写的模块只能在当前路径下的程序里才能导入,换一个目录再导入自己的模块就报错说找不到了, 这是为什么?

这与导入路径有关

import sys

print(sys.path)

输出

[‘D:\\Python\\14_day_training_camp\\Python全栈开发中级\\第二模块\\chapter4-常用模块’, ‘D:\\Python\\14_day_training_camp’, ‘D:\\Python\\14_day_training_camp\\Python全栈开发中级\\第二模块\\chapter4-常用模块\\my_proj’, ‘D:\\Python\\14_day_training_camp\\作业\\第五次作业\\ATM’, ‘D:\\Python\\14_day_training_camp\\Python全栈开发中级\\ATM程序’, ‘D:\\Python36\\python36.zip’, ‘D:\\Python36\\DLLs’, ‘D:\\Python36\\lib’, ‘D:\\Python36’, ‘D:\\Python36\\lib\\site-packages’, ‘D:\\Python36\\lib\\site-packages\\openpyxl-2.3.3-py3.6.egg’, ‘D:\\Python36\\lib\\site-packages\\et_xmlfile-1.0.1-py3.6.egg’, ‘D:\\Python36\\lib\\site-packages\\jdcal-1.3-py3.6.egg’, ‘D:\\Python36\\lib\\site-packages\\file_magic-0.3.0-py3.6.egg’, ‘D:\\Python36\\lib\\site-packages\\win32’, ‘D:\\Python36\\lib\\site-packages\\win32\\lib’, ‘D:\\Python36\\lib\\site-packages\\Pythonwin’, ‘D:\\Program Files\\JetBrains\\PyCharm 2018.1.1\\helpers\\pycharm_matplotlib_backend’]

python解释器会按照列表顺序去依次到每个目录下去匹配你要导入的模块名,只要在一个目录下匹配到了该模块名,就立刻导入,不再继续往后找。

注意列表第一个元素代表当前目录,所以你自己定义的模块在当前目录会被优先导入。

四、开源模块安装、使用

  • pip3 install 模块名
  • 在官网下载源码安装

编译源码 python setup.py build

安装源码 python setup.py install

五、包(package)

当模块文件越来越多,需要对文件按作用不同进行分类

└── my_proj

├── crm #代码目录

│ ├── admin.py

│ ├── apps.py

│ ├── models.py

│ ├── tests.py

│ └── views.py

├── manage.py

└── my_proj #配置文件目录

├── settings.py

├── urls.py

└── wsgi.py

像上面这样,一个文件夹管理多个模块文件,这个文件夹就被称为包

crm/views.py内容

def sayhi():

print('hello world!')

print(settings.DATABASES).

└── my_proj

├── crm #代码目录

│ ├── admin.py

│ ├── apps.py

│ ├── models.py

│ ├── tests.py

│ └── views.py

├── manage.py

└── my_proj #配置文件目录

├── settings.py

├── urls.py

└── wsgi.py

如何实现在crm/views.py里导入proj/settings.py模块?
直接导入的话,会报错,说找到不模块

通过manage.py调用

from crm import views

views.sayhi()

输出:

D:\Python\14_day_training_camp\Python全栈开发中级\第二模块\chapter4-常用模块\my_proj

{'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': 'D:\\Python\\14_day_training_camp\\Python全栈开发中级\\第二模块\\chapter4-常用模块\\my_proj\\db.sqlite3'}}

hello world!

跨模块导入

目录结构如下

据上面的结构,如何实现在crm/views.py里导入proj/settings.py模块?

直接导入的话,会报错,说找到不模块

$ python3 views.py
Traceback (most recent call last):
  File "views.py", line 2, in <module>
    from proj import settings
ModuleNotFoundError: No module named 'proj'
 

是因为路径找不到,proj/settings.py 相当于是crm/views.py的父亲(crm)的兄弟(proj)的儿子(settings.py),settings.py算是views.py的表弟啦,在views.py里只能导入同级别兄弟模块代码,或者子级别包里的模块,根本不知道表弟表哥的存在。这可怎么办呢?

答案是添加环境变量,把父亲级的路径添加到sys.path中,就可以了,这样导入 就相当于从父亲级开始找模块了。

crm/views.py中添加环境变量

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

print(BASE_DIR)

sys.path.append(BASE_DIR)

from my_proj import settings

def sayhi():

print('hello world!')

print(settings.DATABASES)

输出

D:\Python\14_day_training_camp\Python全栈开发中级\第二模块\chapter4-常用模块\my_proj

{'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': 'D:\\Python\\14_day_training_camp\\Python全栈开发中级\\第二模块\\chapter4-常用模块\\my_proj\\db.sqlite3'}}

绝对导入&相对导入

在linux里可以通过cd …回到上一层目录 ,cd …/… 往上回2层,这个…就是指相对路径,在python里,导入也可以通过..

例如:

├── __init__.py

├── crm

│ ├── __init__.py

│ ├── admin.py

│ ├── apps.py

│ ├── models.py

│ ├── tests.py

│ ├── views.py #from ..proj import settings

├── manage.py

└── proj

├── __init__.py

├── settings.py #from .import urls

├── urls.py

└── wsgi.py

views.py里代码

from ..proj import settings

def sayhi():

print('hello world!')

print(settings.DATABASES)

执行结果报错了

Traceback (most recent call last):

File "my_proj/crm/views.py", line 4, in <module>

from ..proj import settings

SystemError: Parent module '' not loaded, cannot perform relative import

或者有人会看到这个错

ValueError: attempted relative import beyond top-level package

其实这两个错误的原因归根结底是一样的:在涉及到相对导入时,package所对应的文件夹必须正确的被python解释器视作package,而不是普通文件夹。否则由于不被视作package,无法利用package之间的嵌套关系实现python中包的相对导入。

文件夹被python解释器视作package需要满足两个条件:

  1. 文件夹中必须有__init__.py文件,该文件可以为空,但必须存在该文件。
  2. 不能作为顶层模块来执行该文件夹中的py文件(即不能作为主函数的入口)。

所以这个问题的解决办法就是,既然你在views.py里执行了相对导入,那就不要把views.py当作入口程序,可以通过上一级的manage.py调用views.py

├── __init__.py

├── crm

│ ├── __init__.py

│ ├── admin.py

│ ├── apps.py

│ ├── models.py

│ ├── tests.py

│ ├── views.py #from ..proj import settings

├── manage.py #from crm import views

└── proj

├── __init__.py

├── settings.py #from .import urls

├── urls.py

└── wsgi.py

事实证明还是不行,报错

ValueError: attempted relative import beyond top-level package 

但把from ..proj import settings 改成from . import models 后却执行成功了,为什么呢?

from .. import models会报错的原因是,这句代码会把manage.py所在的这一层视作package,但实际上它不是,因为package不能是顶层入口代码,若想不出错,只能把manage.py往上再移一层。

正确的代码目录结构如下

再执行manage.py就不会报错了。

注:虽然python支持相对导入,但对模块间的路径关系要求比较严格,处理不当就容易出错,so并不建议在项目里经常使用。

以上就是“避免竞态条件:Python中list、set、dict的线程安全策略”的全部内容,希望对你有所帮助。

关于Python技术储备

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

在这里插入图片描述

二、Python必备开发工具

img

三、Python视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

img

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

img

五、Python练习题

检查学习结果。

img

六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

img

最后祝大家天天进步!!

上面这份完整版的Python全套学习资料已经上传至CSDN官方,朋友如果需要可以直接微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】。

  • 22
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值