澳门新萄京官方网站-www.8455.com-澳门新萄京赌场网址

澳门新萄京官方网站:模块系列,语句在调用多

2019-09-16 作者:www.8455.com   |   浏览(88)

2018年2月27日 于创B515

Python中if __name__=="__main__" 语句在调用多进度Process进程中的成效解析,__name____main__

2018年2月27日 于创B515

  

引言
  近年来备选攻读一下什么样运用Python中的多进度。在翻看有关书籍、网络资料时意识持有代码都带有if __name__=="__main__",在实践的长河中发觉只要在运行代码进度中,未有那句话Python解释器就能报错。固然Python对于multiprocessing的文书档案第17.2.1.1节中【1】提到必需那样使用,可是自个儿觉着并未根本上讲明清楚。由此笔者决定从源码来解释自个儿的吸引。

# 代码0.1错误代码
import multiprocessing as mp
import os

def do():
    print("pid is : %s ..." % os.getpid())

print("parent id is : %s ..." % os.getpid())
p = mp.Process(target=do, args=())
p.start()

# 代码0.2正确代码
import multiprocessing as mp
import os

def do():
    print("pid is : %s ..." % os.getpid())

if __name__ == '__main__':
    print("parent id is : %s ..." % os.getpid())
    p = mp.Process(target=do, args=())
    p.start()

 

难题陈诉
问题
在运作代码-0.1时,会产出RuntimeError,错误提示如下。但是运转代码0.2时就不会,一切顺遂。

    An attempt has been made to start a new process before the current process has finished its bootstrapping phase.
    This probably means that you are not using fork to start your child processes and you have forgotten to use the 
proper idiom in the main module:
       if __name__ == '__main__':
        freeze_support()
        ...
  The "freeze_support()" line can be omitted if the program is not going to be frozen to produce an executable.

 

主题材料时有发生的条件

环境配置
运行环境:  Win10
IDE Sublime Text3

 

简轻巧单表达
  由于Python运转进度中,新创制进程后,过程会导入正在运维的文书,即在运维代码0.1的时候,代码在运营到mp.Process时,新的历程会另行读入改代码,对于未有if __name__=="__main__"保养的代码,新历程都是为是要重新运转的代码,那是子进度又二遍运转mp.Process,然而在multiprocessing.Process的源码中是对子进度再度发生子进度是做了限定的,是差异意的,于是出现如上的谬误提醒。

详见表明
先谈一谈if__name__=="__main__"
  在Python有关__main__的文书档案中【2】表达“__main__”是代码实行时的万丈的命名空间(the name of the scope in which top-level code executes),今世码被视作脚本读入的时候,命名空间会被命名叫“__main__”,对于在本子运维进程中读入的代码命名空间都不会被命名字为“__main__”。那也实属成立的子进程是不会读取__name__=="__main__"爱慕下的代码。

再谈一谈multiprocessing(win32下的源码分析)
multiprocessing依照平台分化会试行不一的代码:在类UNIX系统下是因为操作系统本人补助fork()语句,win32系统由于笔者不扶助fork(),由此在二种系统下multiprocessing会运维区别的代码,如图1 UNIX平台、图2 win32平台(富含在context.py文件中,Process的定义也是在context.py文件中)。

澳门新萄京官方网站 1

图1 对于类UNIX系统平台

澳门新萄京官方网站 2

图2 对于win32系统平台

  Process是二个惊人正视承继的类———其父类是BaseProcess,如图3 Process类的定义。在利用进度中先早先化三个Process实例,然后经过Process.start()来运转子进程。我们继续看关于Process.start()的概念,如图4 BaseProcess类中的start()定义。在里面第105行,调用了self._Popen(self),该函数重定义定义于Process类。该函数按调用顺序最终会跳转到 popen_spwan_win32.py 文书中的Popen类,如图5 Popen类的概念。Popen类在早先话进程中第一调用windows相关接口,生成三个管道(38行),取得对管道读写的句柄,然后生成二个命令行的字符串列表——cmd,如下:

['C:\Program Files\Python35\python.exe', '-B', '-c', 
'from multiprocessing.spawn import spawn_main;spawn_main(pipe_handle=928, parent_pid=9292)', 
'--multiprocessing-fork']

澳门新萄京官方网站 3

图3 Process类的概念

澳门新萄京官方网站 4

图4 BaseProcess类中的start()定义

澳门新萄京官方网站 5澳门新萄京官方网站 6

图5 Popen类的概念

  这几个字符串列表之后经过命令行送入系统,获得相应的子进度和子线程的句柄及子进度和子线程的ID号。在第65、66行是经过pickle方法将需求的数目从父进度传输给子进程。新进度是调用spawn.py文件中的spawn_main函数,如图6 spawnmain的定义。其中第100行的steal_handle()的职能是子进度猎取父进度生成的句柄,用于后续通讯——使用pickle方法从父进度中读取需求数据。而主题材料的出现便是在那今后现身!该代码在第106行调用_main(),其次在第115行调用prepare(),再一次运维到223行时,运转_fixup_main_from_name(),而此时该函数会运转父进度的本子。由此对此未有if__name__=="__main__"珍爱的代码都以要运营的,而此刻在其次次运营Process创立新历程的时候在第123行 if getattr(process.current_process(), '_inheriting', False): 时,由于子进度是持有_inheriting属性,由此会鼓劲出上述错误代码。

澳门新萄京官方网站 7

图6 spawn_main的定义

  对于代码中生成新子进度时所用到的四个才能本身觉很风趣也很郁闷,因而调控继续看下来。上面轻松描述一下五个本领的概貌。

 —— pickle模块

  首先是pickle模块。pickle模块是二个Python中有意识的数量格式,与JSON等不等,是不可能被其余语言识其他格式。在Python中的官方文书档案【3】中比较了pickle模块与JSON的分裂之处,以及介绍了pickle的利用标准。轻便摘录如下:

           pickle与JSON的区别             
  • JSON 是text文本格式而pickle是二进制流
  • JSON 是可读的而pickle是不可读的
  • JSON 可用于其他语言环境,而pickle仅仅用于Python自身
  • JSON 对于Python中的一些内建(built-in)类型会失效,而pickle都是有效的
可以被pickle模块pickle的数据
  • None、True、False
  • 整数、浮点数、复数
  • 字符串、字节、字节数组
  • 包含可以被pickle数据的元组、列表、集合、字典
  • 使用def定义的函数
  • 在模块top-level定义的内建(built-in)函数和类

 

 —— 管道(Pipe)
  这里驾驭管道是从类UNIX系统精晓,因为其知道起来更有助于。管道在类UNIX系统中也是一种文件,在扭转新的子进度的时候将四个进度都事关至同一个管道上,这样就是双工通讯(父亲和儿子进度并行可读可写)。固然要贯彻单工通讯,就停业相应的坦途(一方写一方读)【4】。

参谋文献

 

__name__==__main__ 语句在调用多进度Process进度中的作用剖析,__name____main__ 二〇一八年8月12日 于创B515 引言 近来策动攻读一下哪些行使Pyt...

Python多进度编程手艺实例深入分析,python实例深入分析

正文以实例格局剖析了Python多进程编制程序技艺,有利于进一步Python程序设计技巧。分享给大家供我们参考。具体剖析如下:

一般的话,由于Python的线程有个别限制,举例二十八线程不能够丰富利用多核CPU等主题材料,因而在Python中我们更赞成利用多进程。但在做不封堵的异步UI等情景,咱们也会使用十二线程。本篇小说首要探寻Python多进度的难题。

Python在2.6引进了多进度的建制,并提供了增进的组件及api以造福编写并发应用。multiprocessing包的零部件Process, Queue, Pipe, Lock等零件提供了与八线程类似的效益。使用这么些零部件,能够方便地编写多进度并发程序。

Process

Process的应用有一点点像java.lang.Thread,但Thread是线程。start方法用以运转有些进度。三个回顾的身体力行:

from multiprocessing import Process
import os
import time
def sleeper(name, seconds):
  print "Process ID# %s" % (os.getpid())
  print "Parent Process ID# %s" % (os.getppid())
  print "%s will sleep for %s seconds" % (name, seconds)
  time.sleep(seconds)

if __name__ == "__main__":
  child_proc = Process(target=sleeper, args=('bob', 5))
  child_proc.start()
  print "in parent process after child process start"
  print "parent process abount to join child process"
  child_proc.join()
  print "in parent process after child process join"
  print "the parent's parent process: %s" % (os.getppid())

实例化一个Process必需要钦赐target和args。target是新的历程的输入方法,能够感觉是main方法。args是该措施的参数列表。运转进程类似于运维Thread,必须要调用start方法。也可以三番五次Process,覆盖run方法,在run方法中贯彻该进程的逻辑。调用join方法会阻塞当前调用进度,直到被调用进度运营甘休。
手工业终止三个进度能够调用terminate方法,在UNIX系统中,该方法会发送SIGTERM时域信号量,而在windows系统中,会借助TerminateProcess方法。须要小心的是,exit管理逻辑并不会被实行,该进程的子进程不会被结束,他们只会成为孤儿进度。

Queue

Queue是多进度安全的队列,能够使用Queue达成多进程之间的多寡传递。put方法用以插入数据到行列中,put方法还会有七个可选参数:blocked和timeout。倘若blocked为True(私下认可值),而且timeout为正值,该方法会阻塞timeout钦命的日子,直到该队列有剩余的空间。假若超时,会抛出Queue.Full非凡。要是blocked为False,但该Queue已满,会应声抛出Queue.Full至极。

get方法能够从队列读取并且删除一个成分。同样,get方法有多个可选参数:blocked和timeout。若是blocked为True(暗中认可值),並且timeout为正值,那么在伺机时间内尚未取到任何因素,会抛出Queue.Empty相当。倘若blocked为False,有二种意况存在,要是Queue有多少个值可用,则即时重回该值,否则,假如队列为空,则立刻抛出Queue.Empty相当。Queue的一段示例代码:

from multiprocessing import Process, Queue
def offer(queue):
  queue.put("Hello World")
def test(queue, num):
  queue.put("Hello World: "   str(num))
if __name__ == '__main__':
  q = Queue()
  p1 = Process(target=test, args=(q, 1))
  p1.start()
  p = Process(target=offer, args=(q,))
  p.start()
  p2 = Process(target=test, args=(q, 2))
  p2.start()
  p2 = Process(target=test, args=(q, 3))
  p2.start()
  print q.get()
  print q.get()
  print q.get()
  print q.get()
  print q.close()

输出:

Hello World: 1
Hello World
Hello World: 2
None

Pipes

Pipe方法重返(conn1, conn2)代表二个管道的四个端。Pipe方法有duplex参数,假若duplex参数为True(默许值),那么这么些管道是全双工形式,也正是说conn1和conn2均可收发。duplex为False,conn1只承担接受音信,conn2只承担发送新闻。

send和recv方法分别是出殡和埋葬和承受消息的主意。举个例子,在全双工格局下,能够调用conn1.send出殡和埋葬音讯,conn1.recv接收音信。若无音信可收取,recv方法会一贯不通。假若管道已经被关闭,那么recv方法会抛出EOFError。

from multiprocessing import Process, Pipe

def send(conn):
  conn.send("Hello World")
  conn.close()
if __name__ == '__main__':
  parent_conn, child_conn = Pipe()
  p = Process(target=send, args=(child_conn,))
  p.start()
  print parent_conn.recv()

同步

multiprocessing包提供了Condition, 伊芙nt, Lock, 奥迪R18Lock, Semaphore等零件可用来共同。上面是运用Lock的三个示范:

from multiprocessing import Process, Lock
def l(lock, num):
  lock.acquire() 
  print "Hello Num: %s" % (num)
  lock.release()
if __name__ == '__main__':
  lock = Lock()
for num in range(20):
  Process(target=l, args=(lock, num)).start()

总结

以上是Python multiprocessing库的简练介绍和实例,熟习Java二十多线程开辟的校友是否以为很熟谙,和java的Concurrency API很像,可是javaConcurrency是管理四线程的而已,大家能够直接根据以前Java四线程的经验用那么些API。

感兴趣的心上人能够测量试验运转本文实例以加重精通。相信本文所述对我们Python程序设计的求学有早晚的借鉴价值。

ummm,哈哈以此标题起得多少过于哗然取众了,连友好都有一点不佳意思,求轻拍.

【模块】

  

python 能够先创建多进度,然后再个各样子进度创造四个线程?

能够的,创制多进程用subprocess库,也足以直接os.fork来创设

三十二线程用threading库,那些比较轻易,随意一搜就广大剧情啦。  

上面先从部分相比轻巧的code example最早聊起:

本节目录

  • ### 模块相关介绍

  • ### time

  • ### random

  • ### os

  • ### sys

  • ### json & pickle

  • ### shelve

  • ### xml

  • ### configparser

  • ### hashlib

  • ### subprocess

  • ### optparse

  • ### struct

  • ### 所述一些模块方法并不周全,只是轻松性的学习,或有错误,敬请指正

  • ### 未完待续......

 为啥要有模块:

    在Computer程序的付出进程中,程序代码越写越来越多,在二个py文件中会更加多,变得不轻巧保证

    为了编写制定易维护的代码,将过多函数分组,分别放入分歧的py文件中,各个文件包括的代码就能够相对降低,好多编制程序语言都如此做

    在python中,二个.py文件中就足以叫做贰个模块(moudle)

    使用模块有哪些好处:大大进步了代码的可维护性,也可分别逻辑

    其次,在编辑好三个模块,就足以在另内地点开展援引,不必从0开首

模块有二种:

  • python标准库
  • 其三方模块
  • 应用程序自定义模块  

模块的引用格局:

  1、import语句  1)试行相应文件  2)引进变量名

1
import time        # 导入时间模块    也可以同时导入多个模块,用逗号隔开

  2、from....import 模块名

1
from my_moudle import main

  3、from....import *

      引进一切,即导入模块中享有的项目,不推荐使用。因为引进的别样来源的命名,十分的大概覆盖了已有些定义。

  4、运营本质

1
2
#1 import test
#2 from test import add 

那么,python中是何等找到这个模块呢?

  sys.path,存放的是进行文书的查找路线(意况变量)。但是模块正是经过情状变量去找的.

三个目录中带__iter__.py的文件成为包(package)

  1、用来组织模块  2、幸免同一模块名的争辩

  注意,每一个包目录上边都会有二个__init__.py的文书,这一个文件是必需存在的,不然,Python就把这几个目录当成普通目录(文件夹),并不是三个包。__init__.py能够是空文件,也足以有Python代码,因为__init__.py本人便是贰个模块,而它的模块名就是对应包的名字。

 

                           澳门新萄京官方网站 8

 

此处介绍一下__name__的属性

  三个模块被另一个主次第四回引进时,其主程序将运转。倘若大家想在模块被引进时,模块中的某一程序块不推行,大家能够用__name__品质来使该程序块仅在该模块本人运转时实行。

1
2
3
4
5
6
7
8
9
10
if __name__ == '__main__':
   print('程序自身在运行')
else:
   print('我来自另一模块')
 
python using_name.py
程序自身在运行
 
import using_name
我来自另一模块

  说明: 每一种模块都有一个__name__属性,当其值是'__main__'时,评释该模块本人在运行,不然是被引进。

引言
  近日计划上学一下如何采纳Python中的多进程。在翻看有关书籍、网络资料时开采全部代码都满含if __name__=="__main__",在尝试的进程中发掘只要在运作代码进程中,未有那句话Python解释器就能够报错。尽管Python对于multiprocessing的文书档案第17.2.1.1节中【1】论及必须那样使用,不过自个儿以为并不曾平素上分解清楚。因而笔者主宰从源码来评释自个儿的思疑。

python 并行编制程序

假使你的bsub和那些ABC没怎么关系的话,你能够:
subprocess.Popen("A1;A2",shell=True)
subprocess.Popen("B1;B2",shell=True)
subprocess.Popen("C1;C2",shell=True)

一旦您在win而不再*nix的话,用“&”代替“;”。  

本文以实例方式深入分析了Python多进度编制程序本事,有利于进一步Python程序设计技能。分享给大家供...

multiprocessing达成多进度

from multiprocessing import Process
import os

def subpro():
    print 'there is a sub process which pid is %s' %os.getpid()

if __name__ == '__main__':
    p=Process(target=subpro, name='process_start_test')
    p.start()
    print 'there is a parent process which pid is %s' %os.getpid()

---输出结果
there is a sub process which pid is 21369
there is a parent process which pid is 21368

就这么就会促成了python的多进程了,只要八个步骤

  • 实例化类multiprocess.Process为实例pp=Process(target=subpro, name='process_start_test')
  • 实例p可以调用multiprocess.Process class的办法p.start()

我们就详细看看那七个步骤到底搞了如何鬼

time

   时间相关的操作,时间有二种象征方法:    

      时间戳               一九六七年3月1日之后的秒,即:time.time(),只临时间戳参数技术拓宽加减

      格式化的字符串    二零一四-11-11 11:11,    即:time.strftime('%Y-%m-%d')

      结构化时间          元组包蕴了:年、日、星期等... time.struct_time    即:time.localtime()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
print time.time()
print time.mktime(time.localtime())
    
print time.gmtime()     #可加时间戳参数
print time.localtime()  #可加时间戳参数
print time.strptime('2014-11-11''%Y-%m-%d')
    
print time.strftime('%Y-%m-%d'#默认当前时间
print time.strftime('%Y-%m-%d',time.localtime()) #默认当前时间
print time.asctime()
print time.asctime(time.localtime())
print time.ctime(time.time())
    
import datetime
'''
datetime.date:表示日期的类。常用的属性有year, month, day
datetime.time:表示时间的类。常用的属性有hour, minute, second, microsecond
datetime.datetime:表示日期时间
datetime.timedelta:表示时间间隔,即两个时间点之间的长度
timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]])
strftime("%Y-%m-%d")
'''
import datetime
print datetime.datetime.now()
print datetime.datetime.now() - datetime.timedelta(days=5)

   澳门新萄京官方网站 9

# 代码0.1错误代码
import multiprocessing as mp
import os

def do():
    print("pid is : %s ..." % os.getpid())

print("parent id is : %s ..." % os.getpid())
p = mp.Process(target=do, args=())
p.start()

# 代码0.2正确代码
import multiprocessing as mp
import os

def do():
    print("pid is : %s ..." % os.getpid())

if __name__ == '__main__':
    print("parent id is : %s ..." % os.getpid())
    p = mp.Process(target=do, args=())
    p.start()

1. 实例化Process class

class Process(object):
        _Popen = None
        def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
            assert group is None, 'group argument must be None for now'
            count = _current_process._counter.next()
            self._identity = _current_process._identity   (count,)
            self._authkey = _current_process._authkey
            self._daemonic = _current_process._daemonic
            self._tempdir = _current_process._tempdir
            self._parent_pid = os.getpid()
            self._popen = None
            self._target = target
            self._args = tuple(args)
            self._kwargs = dict(kwargs)
            self._name = name or type(self).__name__   '-'   
                     ':'.join(str(i) for i in self._identity)

在实例化Process我们传进了叁个参数target=subpro,则就能实行发轫化函数(function) init(),就把那几个参数赋予给这一个实例的self._target属性(attribute),那么些参数的含义就是等会调用的便是以此函数subpro
还要在实例化的同时仍是可以够传播一些别的参数,比如args=(), kwarge={},那八个参数是等会作为子进程subpro函数的参数字传送入

random(随机模块)

1
2
3
4
5
6
7
8
9
10
import random                 
print(random.random())         # 0到1的随机浮点数
print(random.randint(1,3))     # 整形 闭区间 [1,3]
print(random.randrange(1,3))   # 整形,开区间 [1,3)
li = [11,22,33,44,55]
print(random.choice(li))       # 基于可迭代对象随机
print(random.sample(li,2))     # 随机选定多个
print(random.uniform(1,2))     # 任意范围的浮点型
random.shuffle(li)             # 随机打乱次序
print(li)

  通过猖狂模块能够创造贰个放肆验证码

澳门新萄京官方网站 10澳门新萄京官方网站 11

def v_code():  
    checkcode = "" # 定义一个空字符串
    for i in range(4): # 遍历四次
        num = random.randint(0,9) # 随机选择0到9的整形
        alf = chr(random.randint(65,90)) # 随机选择chr对应的字母
        add = random.choice([num,alf]) # 基于上面的可迭代对象选择一个
        checkcode  = str(add) # 将它们变为字符串,加到空字符串里面
    return checkcode
if __name__ == "__main__":
    print(v_code())

随意验证码

 

2. 调用实例P的start方法

    def start(self):
        '''
        Start child process
        '''
        assert self._popen is None, 'cannot start a process twice'
        assert self._parent_pid == os.getpid(), 
               'can only start a process object created by current process'
        assert not _current_process._daemonic, 
               'daemonic processes are not allowed to have children'
        _cleanup()
        if self._Popen is not None:
            Popen = self._Popen
        else:
            from .forking import Popen
        self._popen = Popen(self)
        _current_process._children.add(self)

前边的assert都以有个别反省的操作,比方不可能三翻五次进行start()方法一遍,主要的操作是self._popen = Popen(self),就以此操作去调用了子进程,那么我们就看看波普n是何许做到的,Popen类在multiprocess/forking.py内

os

   用于提供系统级其余操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
os.getcwd()                 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname")         改变当前脚本工作目录;相当于shell下cd
os.curdir                   返回当前目录: ('.')
os.pardir                   获取当前目录的父目录字符串名:('..')
os.makedirs('dir1/dir2')    可生成多层递归目录
os.removedirs('dirname1')   若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname')         生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname')         删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname')       列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 ***
os.remove()                 删除一个文件
os.rename("oldname","new")  重命名文件/目录 ***
os.stat('path/filename')    获取文件/目录信息,相关信息的介绍 size 文件大小 atime 上次访问时间 mtime 上次修改时间 ctime 查看创建时间
os.sep                      操作系统特定的路径分隔符,win下为"\",Linux下为"/"
os.linesep                  当前平台使用的行终止符,win下为"tn",Linux下为"n"
os.pathsep                  用于分割文件路径的字符串
os.name                     字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command")   运行shell命令,直接显示
os.environ                  获取系统环境变量
os.path.abspath(path)       返回path规范化的绝对路径
os.path.split(path)         将path分割成目录和文件名二元组返回
os.path.dirname(path)       返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path)      返回path最后的文件名。如何path以/或结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path)        如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path)         如果path是绝对路径,返回True
os.path.isfile(path)        如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path)         如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略,涉及文件路径拼接就用它
os.path.getatime(path)      返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path)      返回path所指向的文件或者目录的最后修改时间

主题素材陈说
问题
在运作代码-0.1时,会现出RuntimeError,错误提示如下。不过运营代码0.2时就不会,一切顺遂。

3. self.popen = Popen(self)

   class Popen(object):

        def __init__(self, process_obj):
            sys.stdout.flush()
            sys.stderr.flush()
            self.returncode = None

            self.pid = os.fork()
            if self.pid == 0:
                if 'random' in sys.modules:
                    import random
                    random.seed()
                code = process_obj._bootstrap()
                sys.stdout.flush()
                sys.stderr.flush()
                os._exit(code)

事实上Popen是一个class,在Process start方法里,大家实例化了这一个类,并传播Process class的多少个实例(process_obj),在初叶化波普n那个类的_init_()方法里面能够看看是行使了os.fork函数来发生三个子历程,然后此子进度去开展process_obj._bootstratp方法。
那就是说正是又绕回multiprocessing/process.py Process类里面了

sys

   提供对Python解释器相关的操作:

1
2
3
4
5
6
7
8
9
sys.argv           命令行参数List,第一个元素是程序本身路径  *****
sys.exit(n)        退出程序,正常退出时exit(0)
sys.version        获取Python解释程序的版本信息
sys.maxint         最大的Int
sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform       返回操作系统平台名称
sys.stdin          输入相关
sys.stdout         输出相关
sys.stderror       错误相关

  通过sys模块能够做个大概的进度的小程序

澳门新萄京官方网站 12澳门新萄京官方网站 13

import sys
import time
def view_bar(num, total):
    rate = float(num) / float(total)
    rate_num = int(rate * 100)
    r = 'r%d%%' % (rate_num, )
    sys.stdout.write(r)
    sys.stdout.flush()
if __name__ == '__main__':
    for i in range(0, 101):
        time.sleep(0.1)
        view_bar(i, 100)
# 未研究

import sys
import time
for i in range(10):
    sys.stdout.write("#")
    sys.stdout.flush()
    time.sleep(1)

进程条突显

    An attempt has been made to start a new process before the current process has finished its bootstrapping phase.
    This probably means that you are not using fork to start your child processes and you have forgotten to use the 
proper idiom in the main module:
       if __name__ == '__main__':
        freeze_support()
        ...
  The "freeze_support()" line can be omitted if the program is not going to be frozen to produce an executable.

4. code = process_obj._bootstrap()

def _bootstrap(self):
        from . import util
        global _current_process

        try:
            self._children = set()
            self._counter = itertools.count(1)
            try:
                sys.stdin.close()
                sys.stdin = open(os.devnull)
            except (OSError, ValueError):
                pass
            _current_process = self
            util._finalizer_registry.clear()
            util._run_after_forkers()
            util.info('child process calling self.run()')
            try:
                self.run()
                exitcode = 0
            finally:
                util._exit_function()

能够看来最重大的步骤是去调用Process class的run方法,恩,又绕回来了

json & pickle

   那是俩个用作于连串化的模块

    json   用于【字符串】和 【python基本数据类型】 间实行转移  *****

       (数据交互),能够开展三种语言的数目交互 

    pickle 用于【python特有的项目】 和 【python基本数据类型】间举办改造  

        Json模块提供了八个效率:dumps、dump、loads、load   无s的分别,应用于文件的操作

 

        pickle模块提供了多少个功效:dumps、dump、loads、load

澳门新萄京官方网站 14澳门新萄京官方网站 15

import json
# json的用法
dic = {"name":"alex"}
data = json.dumps(dic)
print(data)
print(type(data))
with open("hello","w") as f:
    f.write(data)


with open("hello","r") as new_f:
    i = new_f.read()
    a = json.loads(i)
    print(type(i))
    print(type(a))

{"name": "alex"}
<class 'str'>
<class 'str'>
<class 'dict'>

json

json里面都会产生双引号的字符串

    # dct="{'1':111}"#json 不认单引号

     只要符合json字符串,则一贯能够locals

澳门新萄京官方网站 16澳门新萄京官方网站 17

import pickle                # 和json的方法的相同,序列化对象
dic = {"name":"alex"}
# data = pickle.dumps(dic)   # 转化为字节类型
# print(data)                # ---><class 'bytes'>

f = open("hello","wb")
f.write(pickle.dumps(dic))   #
f.close()

f = open("hello","rb")      # 反序列化
data = pickle.loads(f.read())# 相当于data = pickle.load(f)
print(data)
f.close()

pickle

    Pickle的难题和装有其余编制程序语言特有的体系化难题同样,便是它只好用来Python,况兼只怕两样版本的Python互相都不合作,由此,只好用Pickle保存那么些不根本的多寡,不可能学有所成地反种类化也没涉及。

 

5. self.run()

 def run(self):
        '''
        Method to be run in sub-process; can be overridden in sub-class
        '''
        if self._target:
            self._target(*self._args, **self._kwargs)

到这一步终于能见到是什么去实施传进来的函数了,那么大家仍可以够重新定义那么些函数,能够再没有传来target参数也能实施run方法的操作

未完...

shelve

shelve模块比pickle模块轻便,唯有叁个open函数,再次来到类似字典的目的,可读可写;key必得为字符串,而值可以是python所支撑的数据类型,会生成八个文件

1
2
3
4
5
6
7
8
9
10
11
12
import shelve
  
= shelve.open(r'shelve.txt')
  
# f['stu1_info']={'name':'alex','age':'18'}
# f['stu2_info']={'name':'alvin','age':'20'}
# f['school_info']={'website':'oldboyedu.com','city':'beijing'}
#
#
# f.close()
  
print(f.get('stu_info')['age'])

难点发生的情况

xml

  跟json大致,用作完结不相同语言之间的多寡交互,不过json使用起来更简约。

  现今比比较多观念和金融行当的系统的接口仍旧用的xml

  xml的格式如下,正是经过<>节点来差异数据结构的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>                                                  # 有一个xml的数据

   接下来我们能够展开对它操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import xml.etree.ElementTree as ET
tree = ET.parse("xml_t")  # 解析(打开)xml文件
root = tree.getroot() #
print(root.tag) # .tag是取第一层的标签
# 遍历root文档
for child in root:
    print(child.tag,child.attrib) # 取每条的标签名,还有每条标签的属性值(是字典)
    for in child:
        print(i.tag,i.text) # 取子标签下的标签名,还有每条标签下的内容
# 只遍历yaer的节点
for node in root.iter("year"):
    print(node.tag,node.text) # 取出year的标签名,还有year标签名下的内容
#---------------------------------------
import xml.etree.ElementTree as ET
tree = ET.parse("xmltest.xml")
root = tree.getroot()
# 修改
for node in root.iter('year'):   # 只遍历yaer的节点
    new_year = int(node.text)   1 # 将每个year标签下的内容整形并 1
    node.text = str(new_year)
    node.set("updated","yes")    # 添加。set(标签名,属性值)
tree.write("xmltest.xml")        # 写入新的修改的xml文件
# 删除
for country in root.findall('country'): # 遍历标签名为country下的东西
    rank = int(country.find('rank').text)# 找到country下的子标签为rank 取出它的内容,并复制
    if rank > 50# 如果大于50
     root.remove(country) # 则删除country这个标签
 
tree.write('output.xml')
环境配置
运行环境:  Win10
IDE Sublime Text3

configarser

   其实就是布局深入分析文件,有定点的格式

 

澳门新萄京官方网站 18格式

澳门新萄京官方网站 19  

  比如有个简易的文件,如上大家得以对那些相应格式的文本实行部分操作

  1、获取具有节点 sections

1
2
3
4
5
6
import configparser
xx = configparser.ConfigParser()   # 创建一个对象
xx.read("ini",encoding="utf8")     # 读取相应文件
 
result = xx.sections()             # 获取所有节点
print(result)

  2、获取钦定节点下有所的键 options

1
2
3
4
5
6
7
import configparser
xx = configparser.ConfigParser()  # 创建一个对象
# xx的对象的read功能,打开读取文件,放进内容
xx.read("ini",encoding="utf8")    # 读取相应文件
 
result = xx.options("kaixin")     # 获取指定节点下所有的键
print(result)

  3、获取内定节点下全部的键值对 items

1
2
3
4
5
6
7
import configparser
xx = configparser.ConfigParser()  # 创建一个对象
# xx的对象的read功能,打开读取文件,放进内容
xx.read("ini",encoding="utf8")    # 读取相应文件
 
result = xx.items("kaixin")       # 获取指定节点下的所有键值对
print(result)

  4、获取钦赐节点下内定key的值

1
2
result = xx.get("kaixin","age")
print(result)

  5、检查,增加,删除节点

1
2
3
4
5
6
7
8
9
10
11
# 检查节点是否存在,返回的是布尔值
has_sec = xx.has_section("kaixin")
print(has_sec)
 
# 添加节点
xx.add_section("Tom")
xx.write(open("ini","w"))
 
# 删除节点
xx.remove_section("Tom")
xx.write(open("ini","w"))

  6、检查、删除、设置钦点组内的键值对

1
2
3
4
5
6
7
8
9
10
11
# 检查节点下的key值是否存在,返回的是布尔值
has_opt = xx.has_option("kaixin","age")
print(has_opt)
 
# 删除键值对
xx.remove_option("kaixin","money")
xx.write(open("ini","w"))
 
# 设置键值对
xx.set("tony","money","10000")
xx.write(open("ini","w"))

 

hashlib

   用于加密相关的操作,代替了md5模块和sha模块,首要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

1
2
3
4
5
import hashlib
 
hash = hashlib.md5(bytes("bingdu",encoding="utf8")) # 创建md5对象,并额外加密
hash.update(bytes("123",encoding="utf8")) # 对字符串加密
print(hash.hexdigest()) # 取到密文

简单解释
  由于Python运维进程中,新创制进度后,进度会导入正在运营的文书,即在运维代码0.1的时候,代码在运转到mp.Process时,新的经过会另行读入改代码,对于尚未if __name__=="__main__"敬服的代码,新进度都是为是要重国民党的新生活运动行的代码,那是子进程又壹遍运转mp.Process,然则在multiprocessing.Process的源码中是对子进程再一次发生子进度是做了限定的,是分裂意的,于是现身如上的荒谬提示。

subprocess

   能够举行shell命令的相关模块和函数有

  • os.system
  • os.spawn*
  • os.popen*    —废弃
  • popen2.*  —废弃
  • commands.* —遗弃,3.x中被移除

  以上实践shell命令的相干的模块和函数的法力均在 subprocess 模块中贯彻,并提供了更丰盛的效能。

subprocess.Popen(...)

用来推行复杂的系统命令

参数:

  • args:shell命令,能够是字符串恐怕连串类型(如:list,元组)
  • bufsize:内定缓冲。0 无缓冲,1 行缓冲,其余 缓冲区大小,负值 系统缓冲
  • stdin, stdout, stderr:分别表示程序的正统输入、输出、错误句柄
  • preexec_fn:只在Unix平台下有效,用于钦点四个可举办对象(callable object),它将要子进程运维在此以前被调用
  • close_sfs:在windows平台下,如果close_fds被设置为True,则新成立的子进度将不会延续父进度的输入、输出、错误管道。
  • 故而不能够将close_fds设置为True同期重定向子进度的科公输子入、输出与错误(stdin, stdout, stderr)。
  • shell:同上
  • cwd:用于设置子进度的当前目录
  • env:用于钦点子进度的碰到变量。要是env = None,子进度的境况变量将从父进度中承接。
  • universal_newlines:不一致类别的换行符不一样,True -> 同意采取 n
  • startupinfo与createionflags只在windows下有效
  • 将被传送给底层的CreateProcess()函数,用于设置子进度的有的属性,如:主窗口的外观,进程的优先级等等 
  • shell=True:  钦定的下令行会通过shell来推行
  • stdin :   标准输入
  • stdout : 标准输出
  • stderr :  标准错误的文件句柄
  • PIPE :    管道 ,暗许值 为: None, 表示不做重定向,管道能够用来接收数据。

澳门新萄京官方网站 20澳门新萄京官方网站 21

把标准输出放入管道中,屏幕上就不会输出内容。
res=subprocess.Popen("dir", shell=True,stdout=subprocess.PIPE,stdin=subprocess.PIPE,stderr=subprocess.PIPE)   #执行dir命令,交给shell解释器执行,通过标准类型和subprocess.PIPE放入管道中。

>>> res.stdout.read()  #读取管道里面的数据,在程序中,读取也不会输出到屏幕上。

>>> res.stdout.read()   #再read一次,内容就为空,说明读取完成.
b''  #显示为:bytes类型

View Code

详细解释
先谈一谈if__name__=="__main__"
  在Python有关__main__的文书档案中【2】说明“__main__”是代码实行时的万丈的命名空间(the name of the scope in which top-level code executes),今世码被当作脚本读入的时候,命名空间会被命名字为“__main__”,对于在本子运转进度中读入的代码命名空间都不会被命名字为“__main__”。那约等于说创制的子进程是不会读取__name__=="__main__"珍贵下的代码。

optparse

Python 有多个内建的模块用于拍卖命令行参数:

三个是 getopt,《Deep in python》一书中也可能有提到,只可以轻便处理命令行参数;

另三个是 optparse,它功用庞大,並且轻松使用,可以实惠地生成标准的、符合Unix/Posix 标准的命令行表达。

轻巧易行流程

先是必需导入模块optparse(这几个十分少说)

澳门新萄京官方网站 22澳门新萄京官方网站 23

import optparse
# 创建OptionParser类对象
parser = optparse.OptionParser()
# 然后,使用add_option来定义命令行参数(伪代码)
# parser.add_option(opt_str, ...
#                   attr= value,...)
# 每个命令行参数就是由参数名字符串和参数属性组成的。如 -f 或者 –file 分别是长短参数名:
parser.add_option("-f","--file",dest = "filename")
# 最后,一旦你已经定义好了所有的命令行参数,调用 parse_args() 来解析程序的命令行:
options,args = parser.parse_args()

注: 你也可以传递一个命令行参数列表到 parse_args();否则,默认使用 sys.argv[:1]。
parse_args() 返回的两个值:
options,它是一个对象(optpars.Values),保存有命令行参数值。只要知道命令行参数名,如 file,就可以访问其对应的值: options.file 。
args,它是一个由 positional arguments 组成的列表。

View Code

再谈一谈multiprocessing(win32下的源码剖判)
multiprocessing遵照平台不相同会执行不相同的代码:在类UNIX系统下是因为操作系统本人援助fork()语句,win32种类由于自家不帮忙fork(),因而在三种系统下multiprocessing会运作不一致的代码,如图1 UNIX平台、图2 win32阳台(满含在context.py文件中,Process的定义也是在context.py文件中)。

struct

读书到socket互联网编制程序这里,对struct有了认知,今后对它实香港行政局地阐释,也足以相比较可行的减轻粘包难点

struct模块成效:消除bytes和别的二进制数据类型的转移

演示用法:
struct.pack('i',12)

参数表达:

pack函数效率:把自由数据类型产生bytes

i 代表4字节无符号整数。

import struct
struct.pack('i',12) # 用方法pack进行打包,把后面的整形数据,封装成一个bytes类型
b'x0cx00x00x00' # 长度就是4

l=struct.pack('i',12313123)
len(l)
4 #长度就是4

uppack

# 反解
struct.unpack('i',l)
(12313123,)

# 查看类型
l=struct.pack('i',1)
type(l)
<class 'bytes'>  # bytes类型

 

澳门新萄京官方网站 24

图1 对此类UNIX系统平台

澳门新萄京官方网站 25

图2 对此win32种类平台

  Process是壹当中度正视承袭的类———其父类是BaseProcess,如图3 Process类的概念。在动用进程中先开首化二个Process实例,然后经过Process.start()来运营子进度。大家后续看关于Process.start()的定义,如图4 BaseProcess类中的start()定义。在个中第105行,调用了self._蒲柏n(self),该函数重定义定义于Process类。该函数按调用顺序最终会跳转到 popen_spwan_win32.py 文本中的Popen类,如图5 Popen类的概念。Popen类在起先话进程中首先调用windows相关接口,生成二个管道(38行),获得对管道读写的句柄,然后生成贰个命令行的字符串列表——cmd,如下:

['C:\Program Files\Python35\python.exe', '-B', '-c', 
'from multiprocessing.spawn import spawn_main;spawn_main(pipe_handle=928, parent_pid=9292)', 
'--multiprocessing-fork']

澳门新萄京官方网站 26

图3 Process类的定义

澳门新萄京官方网站 27

图4 BaseProcess类中的start()定义

澳门新萄京官方网站 28澳门新萄京官方网站 29

图5 Popen类的定义

  那么些字符串列表之后通过命令行送入系统,得到相应的子进度和子线程的句柄及子进度和子线程的ID号。在第65、66行是透过pickle方法将须要的多寡从父进程传输给子进度。新进程是调用spawn.py文件中的spawn_main函数,如图6 spawnmain的定义。其中第100行的steal_handle()的效果是子进度获得父进度生成的句柄,用于后续通讯——使用pickle方法从父进程中读取供给数据。而难题的面世正是在这未来出现!该代码在第106行调用_main(),其次在第115行调用prepare(),再一次运营到223行时,运维_fixup_main_from_澳门新萄京官方网站:模块系列,语句在调用多进程Process过程中的作用分析。name(),而此刻该函数会运维父进度的剧本。因而对于没有if__name__=="__main__"爱惜的代码都是要运转的,而那时在其次次运转Process成立新进程的时候在第123行 if getattr(process.current_process(), '_inheriting', False): 时,由于子进度是装有_inheriting属性,因而会激情出上述错误代码。

澳门新萄京官方网站 30

图6 spawn_main的定义

  对于代码中生成新子进度时所用到的七个手艺本人觉很有趣也很烦恼,由此调节继续看下来。下边轻便描述一下三个能力的大概。

 —— pickle模块

  首先是pickle模块。pickle模块是三个Python中特有的数额格式,与JSON等不一致,是不能够被别的语言识别的格式。在Python中的官方文书档案【3】中比较了pickle模块与JSON的分化之处,以及介绍了pickle的应用准则。轻松摘录如下:

           pickle与JSON的区别             
  • JSON 是text文本格式而pickle是二进制流
  • JSON 是可读的而pickle是不可读的
  • JSON 可用于其他语言环境,而pickle仅仅用于Python自身
  • JSON 对于Python中的一些内建(built-in)类型会失效,而pickle都是有效的
可以被pickle模块pickle的数据
  • None、True、False
  • 整数、浮点数、复数
  • 字符串、字节、字节数组
  • 包含可以被pickle数据的元组、列表、集合、字典
  • 使用def定义的函数
  • 在模块top-level定义的内建(built-in)函数和类

 

 —— 管道(Pipe)
  这里精通管道是从类UNIX系统领悟,因为其知道起来更方便。管道在类UNIX系统中也是一种文件,在扭转新的子进程的时候将四个进度都涉嫌至同叁个管道上,那样正是双工通信(父亲和儿子进程并行可读可写)。即便要落到实处单工通讯,就倒闭相应的康庄大道(一方写一方读)【4】。

参谋文献

  1. Python3.5 关于multiprocessing的文档  
  2. Python3.5 关于__main__的文档    
  3. Python3.5 关于pickle的文档                       
  4. 网络一片关于pipe的牵线                             

 

本文由澳门新萄京官方网站发布于www.8455.com,转载请注明出处:澳门新萄京官方网站:模块系列,语句在调用多

关键词: