#支持类型提示 typing
{
def greeting(name: str) -> str:
return 'Hello ' + name #在函数greeting中,参数名称的类型为str,返回类型为str。 接受子类型作为参数。
#例子
>>> def gg(name:str)->str:
return 'hello'+name >>> gg('a')
'helloa'
>>> gg('bbb')
'hellobbb'
>>> gg(1)
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
gg(1)
File "<pyshell#16>", line 2, in gg
return 'hello'+name
TypeError: must be str, not int
>>> } base64{ import base64
>>> base64.decodebytes(b'c3Vic2NyaWJlcjpTc01pbmkxQA==').decode('utf8')
'subscriber:SsMini1@'
>>> base64.encodebytes(b'subscriber:SsMini1@')
b'c3Vic2NyaWJlcjpTc01pbmkxQA==\n'
}
#给[1,2,3]加权重
random .choices([1,2,3],[1,1,10]) # asyncio
{
#http://www.cnblogs.com/styier/p/6415850.html 例子 #程序总共等待10s
import asyncio
async def print5s():
print("开始运行!")
await asyncio.sleep(5.0) #挂起后台运行
print("结束运行!") async def print10s():
print("开始运行!")
await asyncio.sleep(10.0) #挂起后台运行
print("结束运行!") loop = asyncio.get_event_loop() loop.create_task(print5s())
loop.create_task(print10s())
loop.run_forever() #程序总共等待5s
import asyncio async def compute(x, y):
print("Compute %s + %s ..." % (x, y))
await asyncio.sleep(5.0)
return x + y async def print_sum(x, y):
result = await compute(x, y)
print("%s + %s = %s" % (x, y, result)) loop = asyncio.get_event_loop()
tasks = [print_sum(1,2),print_sum(3,4)]
loop.run_until_complete(asyncio.wait(tasks))
loop.close() #程序总共等待2s
import asyncio async def my_task(seconds):
print("This task is take {} seconds to cpmplete".format(seconds))
await asyncio.sleep(seconds)
return "task finished" if __name__ == "__main__":
my_event_loop = asyncio.get_event_loop()
tasks = []
try:
print("task creation started")
task_obj1 = my_event_loop.create_task(my_task(seconds = 2))
task_obj2 = my_event_loop.create_task(my_task(seconds = 2))
task_obj3 = my_event_loop.create_task(my_task(seconds = 2))
tasks = [task_obj1,task_obj2,task_obj3] #创建事件循环的列表
#my_event_loop.run_until_complete(tasks)
my_event_loop.run_until_complete(asyncio.wait(tasks)) #创建事件循环的列表
finally:
my_event_loop.close() #可以看出 是在同一个线程中执行的
import threading
import asyncio async def hello():
print('Hello world! (%s)' % threading.currentThread())
asyncio.sleep(1)
print('Hello again! (%s)' % threading.currentThread()) loop = asyncio.get_event_loop()
tasks = [hello(), hello()]
loop.run_until_complete(asyncio.wait(tasks))
loop.close() #使用Process类控制子进程和StreamReader类从标准输出读取的示例。子过程由create_subprocess_exec()函数创建:
import asyncio.subprocess
import sys @asyncio.coroutine
def get_date():
code = 'import datetime; print(datetime.datetime.now())' # Create the subprocess, redirect the standard output into a pipe
create = asyncio.create_subprocess_exec(sys.executable, '-c', code,
stdout=asyncio.subprocess.PIPE)
proc = yield from create # Read one line of output
data = yield from proc.stdout.readline()
line = data.decode('ascii').rstrip() # Wait for the subprocess exit
yield from proc.wait()
return line if sys.platform == "win32":
loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)
else:
loop = asyncio.get_event_loop() date = loop.run_until_complete(get_date())
print("Current date: %s" % date)
loop.close() }
queue 队列
{ import queue
#测试定义类传入队列
class Foo(object):
def __init__(self,n):
self.n = n
new = queue.Queue(maxsize=3)
print('先进先出')
new.put(1)
new.put(Foo(1),timeout=2) # 超时时间后,抛出队列full异常
new.put([1, 2, 3],timeout=2)
print(new.full()) #判断队列是否满 True
#new.put("abc",timeout=1) #队列已满,再放报错
print(new.qsize()) # 查看当前队列长度
print(new.get())
print(new.get())
print(new.get())
print(new.empty()) #判断队列是否为空 True
#print(new.get_nowait()) #队列已空,取不到数据报异常
print('后进先出')
q = queue.LifoQueue() #指定使用LifoQueue
q.put(3)
q.put(2)
print(q.get_nowait())
print(q.get_nowait()) print('存入一个元组,第一个为优先级,第二个为数据,第三个默认超时时间')
new = queue.PriorityQueue(maxsize=3)
new.put((10,[1,2,3]))
new.put((5,"strings"))
new.put((20,"strings"))
print(new.get_nowait())
print(new.get_nowait())
print(new.get_nowait()) import threading, queue, time
#生产者消费者模型为了程序松耦合,多对多
def consumer(n):
while True:
print(" consumer [%s] get task: %s" % (n, q.get()))
time.sleep(1) # 每秒吃一个
q.task_done() # get()1次通知队列减少1 def producter(n):
count = 1
while True:
print("producter [%s] produced a new task : %s" % (n, count))
q.put(count)
count += 1
q.join() #消息阻塞 队列为空重新触发
print("all task has been cosumed by consumers ...") q = queue.Queue()
c1 = threading.Thread(target=consumer, args=[1, ])
c2 = threading.Thread(target=consumer, args=[2, ])
c3 = threading.Thread(target=consumer, args=[3, ])
p1 = threading.Thread(target=producter, args=["p1", ])
p2 = threading.Thread(target=producter, args=["p2", ])
c1.start()
c2.start()
c3.start()
p1.start()
p2.start() }
####################################################################################################
#1.研究pty项目sh中,为什么在第一个pythonshell中导入ifconfig后能获取返回,两个伪终端如何传递数据库的?
#2.在子进程中执行shell后返回结果到父进程 在不使用subprocess的情况下,进程间怎么交互数据
#################################################################################################### 1.os.popen() 调用的是subprocess 库,找到subprocess.Popen('dwad',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
{
def __init__(self, args, bufsize=-1, executable=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
shell=False, cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0,
restore_signals=True, start_new_session=False,
pass_fds=(), *, encoding=None, errors=None): 感觉全是io库中的函数 os.openpty() # 打开一个新的伪终端对。返回 pty 和 tty 的文件描述符。
os.pipe() # 创建一个管道. 返回一对文件描述符(r, w) 分别为读和写
os.popen(command[, mode[, bufsize]]) # 从一个 command 打开一个管道
os.read(fd, n) # 从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd对应文件已达到结尾, 返回一个空字符串。
os.write(fd, str) # 写入字符串到文件描述符 fd中. 返回实际写入的字符串长度
os.ttyname(fd) # 返回一个字符串,它表示与文件描述符fd 关联的终端设备。如果fd 没有与终端设备关联,则引发一个异常。 '''
os.dup2(fd,fd2,inheritable = True)
#将文件描述符fd重复到fd2,如有必要,关闭后者。
''' >>> os.pipe() #8用于写,7用于读
(7, 8)
>>> os.write(8,b'1122')
4
>>> os.read(7,10)
b'1122' >>> os.openpty()
(11, 12)
>>> os.ttyname(11)
'/dev/ptmx'
>>> os.ttyname(12) #并没有在linux上真实产生一个/dev/pts/9
'/dev/pts/9' 11是主,12是从
#任何从主设备的输入都会输出到从设备上 #! /usr/bin/env python
#coding=utf-8 import pty
import os
import select def mkpty():
# 打开伪终端
master1, slave = pty.openpty()
slaveName1 = os.ttyname(slave)
master2, slave = pty.openpty()
slaveName2 = os.ttyname(slave)
print ('\nslave device names: ', slaveName1, slaveName2)
return master1, master2 if __name__ == "__main__": master1, master2 = mkpty()
while True: rl, wl, el = select.select([master1,master2], [], [], 1)
for master in rl:
data = os.read(master, 128)
print ("read %d data." % len(data))
if master==master1:
os.write(master2, data)
else:
os.write(master1, data) python3.4 test_pty.py &
#另一终端上执行
root@api:/home/lgj/pty# echo 11 > /dev/pts/12
root@api:/home/lgj/pty# echo 11 > /dev/pts/11 #本终端显示
root@api:/home/lgj/pty# read 4 data.
the data: b'11\r\n'
root@api:/home/lgj/pty# read 4 data.
the data: b'11\r\n'
#主从伪终端
>>> os.openpty()
(4, 5)
>>> os.ttyname(4)
'/dev/ptmx'
>>> os.ttyname(5)
'/dev/pts/9'
>>> os.write(4,b'ls\r\n')
4
>>> os.read(4,100)
b'ls\r\n\r\n'
>>> os.read(5,100)
b'ls\n'
>>> os.read(5,100)
b'\n' #管道
>>> os.pipe()
(6, 7)
>>> os.write(7,str(1).encode('utf-8'))
1
>>> os.read(6,10)
b'1' >>> a=open("lgj",'a')
>>> a.fileno() #文件句柄
8
>>> os.dup(8) #复制文件句柄
9 '''
os.dup2(fd,fd2,inheritable = True)
#将文件描述符fd重复到fd2,如有必要,关闭后者。
''' 命令tty 查看当前终端对应的设备
ps -ax 查看进程对应的控制台 pts(pseudo-terminal slave)是pty的实现方法,与ptmx(pseudo-terminal master)配合使用实现pty。
1、串行端口终端(/dev/ttySn)
2、伪终端(/dev/pty/)
3、控制终端(/dev/tty)
4、控制台终端(/dev/ttyn, /dev/console)
5 虚拟终端(/dev/pts/n)
/dev/tty代表当前tty设备,在当前的终端中输入 echo “hello” > /dev/tty ,都会直接显示在当前的终端中。 os.execv("/sbin/ifconfig",('-a',)) #可以输出ifconfig的返回 #应该是在子进程中执行os.execv("/sbin/ifconfig",('-a',)) 然后读取输出。 '''
stdin,stdout是设置是否打开这些管道,如果他的值是subprocess.PIPE的话,就会打开,同stdin一样的还有stderr
参数stdin, stdout, stderr分别表示程序的标准输入、输出、错误句柄。他们可以是PIPE,文件描述符或文件对象,也可以设置为None,表示从父进程继承。
可以在Popen()建立子进程的时候改变标准输入、标准输出和标准错误,并可以利用subprocess.PIPE将多个子进程的输入和输出连接在一起,构成管道(pipe): import subprocess
child1 = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE)
child2 = subprocess.Popen(["wc"], stdin=child1.stdout,stdout=subprocess.PIPE)
out = child2.communicate()
print(out)
# http://www.cnblogs.com/icejoywoo/p/3627397.html
# http://www.cnblogs.com/yangxudong/p/3753846.html
在POSIX上,subprocess类使用os.execvp() - 类行为来执行子程序。 在Windows上,类使用Windows CreateProcess()函数
'''
sys.stdin.fileno()
>>> import os
>>> import sys
>>> sys.stdin.fileno()
0
>>> os.ttyname(0)
'/dev/pts/2'
>>> os.ttyname(1)
'/dev/pts/2'
>>> os.ttyname(2)
'/dev/pts/2'
>>> os.ttyname(3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 9] Bad file descriptor
>>>
>>> os.openpty()
(4, 5)
>>> os.ttyname(4)
'/dev/ptmx'
>>> os.ttyname(5)
'/dev/pts/10' fd_r_list, fd_w_list, fd_e_list = select.select(rlist, wlist, xlist, [timeout]) 参数: 可接受四个参数(前三个必须)
rlist: wait until ready for reading
wlist: wait until ready for writing
xlist: wait for an “exceptional condition”
timeout: 超时时间 返回值:三个列表 select方法用来监视文件描述符(当文件描述符条件不满足时,select会阻塞),当某个文件描述符状态改变后,会返回三个列表
1、当参数1 序列中的fd满足“可读”条件时,则获取发生变化的fd并添加到fd_r_list中
2、当参数2 序列中含有fd时,则将该序列中所有的fd添加到 fd_w_list中
3、当参数3 序列中的fd发生错误时,则将该发生错误的fd添加到 fd_e_list中 }
#os.fork()
{
ret = os.fork()
if ret == 0:
child_suite # 子进程代码
else:
parent_suite # 父进程代码 #Python中的fork() 函数可以获得系统中进程的PID ( Process ID ),返回0则为子进程,否则就是父进程,然后可以据此对运行中的进程进行操作;
} #异步执行
os.fork()
{ import os
import sys
import time processNmae = '父进程'
print ("Program executing ntpid:%d,processNmae:%s"%(os.getpid(),processNmae))
#attempt to fork child process
try:
forkPid = os.fork()
except OSError:
sys.exit("Unable to create new process.")
# Am I parent process?
if forkPid != 0:
processName = "父进程"
print ("Parent executingn"+"tpid:%d,forkPid:%d,processNmae:%s"%(os.getpid(), forkPid,processName))
# Am I child process?
elif forkPid == 0:
processName = "子进程"
print ("Child executingn" + "tpid: %d, forkPid: %d, processName: %s" % (os.getpid(), forkPid,processName))
print ("Process finishingntpid: %d, processName: %s" % (os.getpid(), processName)) ''' 都能打印在一起,应该是子进程继承了父进程的输入输出端
root@api:/home/lgj/pty# python3.4 cmd_pty2.py
Program executing ntpid:121728,processNmae:父进程
Parent executingntpid:121728,forkPid:121729,processNmae:父进程
Child executingntpid: 121729, forkPid: 0, processName: 子进程
Process finishingntpid: 121729, processName: 子进程 #########################下面这段话很重要##############################
程序每次执行时,操作系统就会创建一个新的进程来运行程序指令。进程还可以调用os.fork,要求操作系统新建一个进程。“父进程”是调用os.fork的进程。父进程所创建的任何进程都是子进程。每个进程都有一个不重复的“进程ID号”,或称“pid”,它对进程进程进行标识。进程调用fork函数时,操作系统会新建一个子进程,它本质上与父进程完全相同。子进程从父进程继承了多个值的拷贝,比如全局变量和环境变量。两个进程唯一的区别就是fork的返回值。
child(子)进程接收返回值为0,而父进程接收子进程的pid作为返回值。调用fork函数后,两个进程并发执行同一个程序,首先执行的是调用了fork之后的下一行代码。父进程和子进程既并发执行,又相互独立;也就是说,它们是“异步执行”的。
''' '''
pid, fd =os.forkpty()
分叉子进程,使用新的伪终端作为子进程的控制终端。 返回一对(pid,fd),其中pid在新子进程中为0,在父进程中为新子进程在父进程中的id,fd是伪终端的主端的文件描述符。 对于更便携的方法,使用pty模块。 如果出现错误,则引发OSError。
>>> os.forkpty()
(123573, 4)
>>> os.ttyname(4)
'/dev/ptmx'
''' } #子进程与父进程(pid,ppid)
{
import os
import sys
def runpager():
fdin, fdout = os.pipe()
pid = os.fork()
print("fdin,fdout,pid,ppid",fdin,fdout,pid,os.getppid())
print("sys.stdin.fileno(),sys.stdout.fileno(),sys.stderr.fileno()",sys.stdin.fileno(),sys.stdout.fileno(),sys.stderr.fileno())
if pid == 0:
os.close(fdin)
os.dup2(fdout, sys.stdout.fileno())
os.dup2(fdout, sys.stderr.fileno())
os.close(fdout)
return
os.dup2(fdin, sys.stdin.fileno())
os.close(fdin)
os.close(fdout)
#os.execvp('/bin/ls', ['/bin/ls', '-l'])
os.execvp('/bin/sleep', ['/bin/sleep','10']) a=input("a=")
print("pid",os.getpid())
print("ppid",os.getppid())
runpager() '''
########################################################################## root@api:/home/lgj/pty# python3.4 cmd_pty1.py
a=1
pid 118983
ppid 109823
fdin,fdout,pid,ppid 3 4 119005 109823
sys.stdin.fileno(),sys.stdout.fileno(),sys.stderr.fileno() 0 1 2
fdin,fdout,pid,ppid 3 4 0 118983
sys.stdin.fileno(),sys.stdout.fileno(),sys.stderr.fileno() 0 1 2 root@api:~# ps -ef|grep python
root 118983 109823 0 16:29 pts/10 00:00:00 python3.4 cmd_pty1.py
root@api:~# ps -ef|grep sleep
root 118996 115824 0 16:29 pts/2 00:00:00 grep --color=auto sleep
root@api:~#
##输入a后
root@api:~# ps -ef|grep python
root 119005 118983 0 16:29 pts/10 00:00:00 [python3.4] <defunct>
root@api:~# ps -ef|grep sleep
root 118983 109823 0 16:29 pts/10 00:00:00 /bin/sleep 10
root@api:~# #exec 函数都执行一个新的程序,然后用新的程序替换当前子进程的进程空间,而该子进程从新程序的main函数开始执行。在Unix下,该新程序的进程id是原来被替换的子进程的进程id。在原来子进程中打开的所有描述符默认都是可用的,不会被关闭。
##########################################################################
root@api:~# ps -ef|grep python
root 115968 115967 0 16:05 pts/10 00:00:00 [python3.4] <defunct>
root 115974 115824 0 16:06 pts/2 00:00:00 grep --color=auto python
PID PPID
UID //用户ID、但输出的是用户名
PID //进程的ID
PPID //父进程ID >>> import os
>>> os.getuid()
0
>>> os.getpid()
116485
>>> os.getppid()
115824 root@api:~# ps -ef|grep python
root 116485 115824 0 16:10 pts/2 00:00:00 python3.4
root 116565 116523 0 16:11 pts/11 00:00:00 grep --color=auto python ''' } #Python进程间通信之匿名管道
{ #管道是一个单向通道,有点类似共享内存缓存.管道有两端,包括输入端和输出端.对于一个进程的而言,它只能看到管道一端,即要么是输入端要么是输出端. os.pipe()返回2个文件描述符(r, w),表示可读的和可写的.示例代码如下: #!/usr/bin/python
import time
import os def child(wpipe):
print('hello from child', os.getpid())
while True:
msg = 'how are you\n'.encode()
os.write(wpipe, msg)
time.sleep(1) def parent():
rpipe, wpipe = os.pipe()
pid = os.fork()
if pid == 0:
child(wpipe)
assert False, 'fork child process error!'
else:
os.close(wpipe)
print('hello from parent', os.getpid(), pid)
while True:
recv = os.read(rpipe, 32)
print (recv) parent()
输出如下: ('hello from parent', 5053, 5054)
('hello from child', 5054)
how are you how are you how are you how are you
我们也可以改进代码,不用os.read()从管道中读取二进制字节,而是从文件对象中读取字符串.这时需要用到os.fdopen()把底层的文件描述符(管道)包装成文件对象,然后再用文件对象中的readline()方法读取.这里请注意文件对象的readline()方法总是读取有换行符’\n’的一行,而且连换行符也读取出来.还有一点要改进的地方是,把父进程和子进程的管道中不用的一端关闭掉. #!/usr/bin/python
import time
import os def child(wpipe):
print('hello from child', os.getpid())
while True:
msg = 'how are you\n'.encode()
os.write(wpipe, msg)
time.sleep(1) def parent():
rpipe, wpipe = os.pipe()
pid = os.fork()
if pid == 0:
os.close(rpipe)
child(wpipe)
assert False, 'fork child process error!'
else:
os.close(wpipe)
print('hello from parent', os.getpid(), pid)
fobj = os.fdopen(rpipe, 'r')
while True:
recv = fobj.readline()[:-1]
print (recv) parent()
输出如下: ('hello from parent', 5108, 5109)
('hello from child', 5109)
how are you
how are you #如果要与子进程进行双向通信,只有一个pipe管道是不够的,需要2个pipe管道才行.以下示例在父进程新建了2个管道,然后再fork子进程.os.dup2()实现输出和输入的重定向.spawn功能类似于subprocess.Popen(),既能发送消息给子进程,由能从子子进程获取返回数据.
​ #!/usr/bin/python
#coding=utf-8
import os, sys def spawn(prog, *args):
stdinFd = sys.stdin.fileno()
stdoutFd = sys.stdout.fileno() parentStdin, childStdout = os.pipe()
childStdin, parentStdout= os.pipe() pid = os.fork()
#程序分叉,子进程中关闭父进程的文件符并将自己用到的文件符重定向到通道,父进程中关闭子进程的文件符并将自己用到的文件符重定向到通道
if pid: #父进程
os.close(childStdin)
os.close(childStdout)
os.dup2(parentStdin, stdinFd)#输入流绑定到管道,将输入重定向到管道一端parentStdin
os.dup2(parentStdout, stdoutFd)#输出流绑定到管道,发送到子进程childStdin
else: #子进程
os.close(parentStdin)
os.close(parentStdout)
os.dup2(childStdin, stdinFd)#输入流绑定到管道
os.dup2(childStdout, stdoutFd)
args = (prog, ) + args
os.execvp(prog, args)
assert False, 'execvp failed!' if __name__ == '__main__':
mypid = os.getpid()
spawn('python', 'pipetest.py', 'spam') print 'Hello 1 from parent', mypid #打印到输出流parentStdout, 经管道发送到子进程childStdin
sys.stdout.flush()
reply = raw_input()
sys.stderr.write('Parent got: "%s"\n' % reply)#stderr没有绑定到管道上 print 'Hello 2 from parent', mypid
sys.stdout.flush()
reply = sys.stdin.readline()#另外一种方式获得子进程返回信息
sys.stderr.write('Parent got: "%s"\n' % reply[:-1]) pipetest.py代码如下: #coding=utf-8
import os, time, sys mypid = os.getpid()
parentpid = os.getppid()
sys.stderr.write('child %d of %d got arg: "%s"\n' %(mypid, parentpid, sys.argv[1])) for i in range(2):
time.sleep(3)
recv = raw_input()#从管道获取数据,来源于父经常stdout
time.sleep(3)
send = 'Child %d got: [%s]' % (mypid, recv)
print(send)#stdout绑定到管道上,发送到父进程stdin
sys.stdout.flush()
输出: child 7265 of 7264 got arg: "spam"
Parent got: "Child 7265 got: [Hello 1 from parent 7264]"
Parent got: "Child 7265 got: [Hello 2 from parent 7264]" } #伪终端tty\pty
{
import os
import sys
import time
import pty
import select
#################使用pty和select 处理子进程的返回, 这样的用例是不能在shell中一步一步敲的,因为存在两个进程
pid, fd = pty.fork()
print(pid) #你会发现这里打印了两个值
mystr=""
#处理子进程
if pid == 0:
os.execvp('/bin/ls', ['/bin/ls', '-l'])
#处理父进程,监听子进程中的返回
if pid !=0:
while True:
i, o, e = select.select([fd], [], [], 2)
if fd in i:
try:
bytes = os.read(fd,600)
mystr=bytes.decode("utf-8")+mystr
print(bytes.decode("utf-8"))
except OSError:
print("子进程监听结束")
break
#继续处理父进程
print("==============")
print(mystr) #父进程中取得了子进程的返回! '''
pid, fd = pty.fork()
程序分叉。 将子进程的控制终端连接到伪终端,返回值为(pid,fd)。注意: 子进程获取pid为0,fd在子进程中是无效的。fork返回非0的pid是子进程的在父进程中的pid,fd是连接到子进程的控制终端(以及子进程的标准输入和输出)的文件描述符。 fd_r_list, fd_w_list, fd_e_list = select.select(rlist, wlist, xlist, [timeout])
select方法用来监视文件描述符(当文件描述符条件不满足时,select会阻塞),当某个文件描述符状态改变后,会返回三个列表
1、当参数1 序列中的fd满足“可读”条件时,则获取发生变化的fd并添加到fd_r_list中
2、当参数2 序列中含有fd时,则将该序列中所有的fd添加到 fd_w_list中
3、当参数3 序列中的fd发生错误时,则将该发生错误的fd添加到 fd_e_list中
'''
#################使用os.fork,pipe 处理子进程的返回,不使用pty又怎么写呢?pty.fork会把子进程的fd返回给父进程读取,这样很方便进程间的交流。
'''
os.dup2(fd,fd2,inheritable = True) #最大的作用就是重定向,将fd2重定向到fd。
#将文件描述符fd重复到fd2,如有必要,关闭后者。
'''
##通常一个进程打开伪终端设备,然后调用fork。子进程建立了一个新会话,打开一个相应的伪终端从设备,将其描述符复制到标准输入、标准输出和标准出错,然后调用exec。伪终端从设备成为子进程的控制终端。
# encoding: utf-8
import os
import sys
import time def child(master, slave):
os.close(master) #关闭不需要的主设备,因为主设备是给父进程传送指令到子进程的
os.dup2(slave, 0) #最大的作用就是重定向,将子进程中的0,1,2 都重定向到从端。
os.dup2(slave, 1)
os.dup2(slave, 2)
os.execvp("/bin/bash", ["bash", "-l", "-i"])
#os.execvp("/bin/ls", ["bash", "-l", "-i"]) def parent():
master, slave = os.openpty() #新建虚拟终端,将从端分配给子进程,主端给主进程。#打开一个新的伪终端对。 分别为pty和tty返回一对文件描述符(主,从)
new_pid = os.fork()
if new_pid == 0:
child(master, slave) time.sleep(0.1)
os.close(slave) #关闭主进程中的从设备 os.write(master, b"fg\n") #把作业放置前台执行,下发指令到子进程,将子进程中的执行放到前台
time.sleep(0.1)
# _ = os.read(master, 1024) #>>见后面的解析1 #os.write(master, (sys.argv[1] + "\n").encode('utf8'))
time.sleep(0.1)
lines = []
while True:
tmp = os.read(master, 1024)
tmp=tmp.decode('utf8')
lines.append(tmp)
if len(tmp) < 1024:
break
output = "".join(lines)
output = "\n".join(output.splitlines()[1:])
print (output) parent() '''
#执行结果
解析1,注释掉后会多打印这些东西。这些是父进程中的多余数据,可以先读出丢弃
bash: no job control in this shell
root@api:/home/lgj/pty# fg
bash: fg: no job control
root@api:/home/lgj/pty# ll bg(将作业放置于后台执行)(在前台执行时间过长,则可以按ctrl+z,暂停进程,用bg放其至后台)
bg 作业ID
fg(把作业放置前台执行)
jobs(查看后台作业) #http://www.cnblogs.com/nufangrensheng/p/3577853.html
##通常一个进程打开伪终端设备,然后调用fork。子进程建立了一个新会话,打开一个相应的伪终端从设备,将其描述符复制到标准输入、标准输出和标准出错,然后调用exec。伪终端从设备成为子进程的控制终端。 对于ssh,telnet等远程登录程序而言,当你ssh到某个sshd服务器上去时,这个sshd会打开一个伪终端主设备,然后fork出一个子进程,在子进程中打开一个从设备,
这样,主进程和子进程之间就可以通过伪终端的主从设备进行交流,任何从主设备的输入都会输出到从设备上
使用主从伪终端之后,当sshd收到指令时会将指令输入到主设备,然后主设备会把执行输出到从设备,这样就相当于指令输入到了从设备,而从设备是和某个shell连接的,从而这个指令或者毫无意义的字符串就被发往了远程的shell去解释
''' #使用 python3.4 cmd_pty1.py ls } {
try ... except 语句可以带有一个 else子句 ,该子句只能出现在 有 except 子句之
后。 try语句没有出现异常时,还想要行执行一些代码,可以使这个子句。例 :
for arg in sys.argv[1:]:
try:
f = open(arg, ’r’)
except IOError:
print(’cannot open’, arg)
else:
print(arg, ’has’, len(f.readlines()), ’lines’)
f.close()
#例子
def dome():
try:
a=7
print(1)
except OSError:
print(2)
else:
print(3)
return a
a=8
print(5)
return a print(dome()) '''result
1
3
7
''' }
双通道
{
#!/usr/bin/python
import time
import os def child(wpipe,rpipe1):
print("""child's pid:""", os.getpid())
for x in range(100):
print("子程序读取到:",os.read(rpipe1,1024))
msg = (str(x)+'from son\n').encode()
print("子进程发送:")
os.write(wpipe, msg)
time.sleep(1) def parent():
rpipe, wpipe = os.pipe() #子进程的写,和父进程的读
rpipe1, wpipe1 = os.pipe() #父进程的写,和子进程的读
pid = os.fork()
if pid == 0:
os.close(rpipe)
os.close(wpipe1)
child(wpipe,rpipe1)
assert False, 'fork child process error!'
else:
os.close(wpipe)
os.close(rpipe1)
print("""parent,child's pid:""", os.getpid(), pid)
fobj = os.fdopen(rpipe, 'r')
for x in range(100):
print("父进程发送:")
os.write(wpipe1,(str(x)+'from father\n').encode())
print("父进程读取:")
print (fobj.readline()) parent()
} 蒙提霍尔问题
{
"""蒙提霍尔问题:
有一个游戏 节目,参赛者会看见三扇关闭了的门,其中一扇的后面有一辆汽车,
选中后面有车的那扇门就可以赢得该汽车,而另外两扇门后面则各藏有一只山羊。
当参赛者选定了一扇门,但未去开启它的时候,节目主持人开启剩下两扇门的其中一扇,
露出其中一只山羊。主持人其后会问参赛者要不要换另一扇仍然关上的门。
问题是:换另一扇门会否增加参赛者赢得汽车的机会率?换与不换赢得汽车的概率分别是多少?
"""
import random
def guess(ischange):
wintimes=0
for a in range(1,1000): #游戏进行1000次
carid=random.randint (0,2)
yourguessid=random.randint (0,2) if carid==yourguessid: #第一次选择就是汽车,主持人随机开一个空门
openid=[x for x in range(0,3) if x !=carid][random.randint (0,1)]
if carid !=yourguessid: #第一次选择不是汽车,主持人开另一个空门
for b in range(0,3):
if b!=yourguessid and b!=carid:
openid=b
#print("主持人开启一门后,carid,yourguessid,openid:",carid,yourguessid,openid)
if ischange:
for c in range(0,3):
if c != openid and c != yourguessid:
yourguessid=c
#print(yourguessid)
break
#print("交换后,carid,yourguessid,openid:",carid,yourguessid,openid)
if carid==yourguessid:
wintimes+=1
print("wintimes:",wintimes) print("不换赢的次数:")
guess(False)
print("换后赢的次数:")
guess(True) """
被主持人打开一个有羊的门之后,剩下的两个的概率不是各50%,因为已不是随机概率了(已被知情的主持人处理过)。
换另一个赢的概率是2/3,要换。 也许有人对此答案提出质疑,认为在剩下未开启的两扇门后有汽车的概率都是1/2,因此不需要改猜。为消除这一质疑,
不妨假定有10扇门的情形,其中一扇门后面有一辆汽车,另外9扇门后面各有一只山羊。
当竞猜者猜了一扇门但尚未开启时,主持人去开启剩下9扇门中的8扇,露出的全是山羊。
显然:原先猜的那扇门后面有一辆汽车的概率只是1/10,这时改猜另一扇未开启的门赢得汽车的概率是9/10。 若主持人不知情,则概率无变化。剩余两门:1/2,1/2,无放回抽样类似。
若主持人知情,概率就会发生变化。剩余两门:未开门的概率为2/3,1/3,非概率事件。 其实这个问题根本就不复杂,大家无论说50%还是66.6%都没有错,因为驳论的关键就在整个事件的条件设置上!
只是多数人不在意提问的所基于的整个条件设置,或者提出这个问题的人没有强调或者交代清楚整个设置,所以才很容易出现不一样的理解和答案。
关键还是在于条件混淆了大家思考的逻辑的起始点还有时间点
"""
#参考博客
http://www.cnblogs.com/antineutrino/p/4821580.html }

python3.6 新特性学习的更多相关文章

  1. Java8 新特性学习 Lambda表达式 和 Stream 用法案例

    Java8 新特性学习 Lambda表达式 和 Stream 用法案例 学习参考文章: https://www.cnblogs.com/coprince/p/8692972.html 1.使用lamb ...

  2. java8 新特性学习笔记

    Java8新特性 学习笔记 1主要内容 Lambda 表达式 函数式接口 方法引用与构造器引用 Stream API 接口中的默认方法与静态方法 新时间日期 API 其他新特性 2 简洁 速度更快 修 ...

  3. 字符串格式的方法%s、format和python3.6新特性f-string和类型注解

    一.%s msg = '我叫%s,今年%s,性别%s' %('帅哥',18,'男') print(msg) # 我叫帅哥,今年18,性别男 二.format # 三种方式: # 第一种:按顺序接收参数 ...

  4. python3.8 新特性

    https://docs.python.org/3.8/whatsnew/3.8.html python 3.8的新功能本文解释了与3.7相比,python 3.8中的新特性. 有关完整的详细信息,请 ...

  5. ES7/8新特性学习随笔

    随着每年EcmaScript都会为js带来一些新特性,带来更多美化的编程体验,今天就走进一下es2016/2017所带来的新特性 ES7新特性 includes() 指数操作符 ES8新特性 asyn ...

  6. java8新特性学习1

    java8增加了不少新特性,下面就一些常见的新特性进行学习... 1.接口中的方法 2.函数式接口 3.Lambda表达式 4.java8内置的四大核心函数式接口 5.方法引用和构造器引用 6.Str ...

  7. java8新特性学习:函数式接口

    本文概要 什么是函数式接口? 如何定义函数式接口? 常用的函数式接口 函数式接口语法注意事项 总结 1. 什么是函数式接口? 函数式接口其实本质上还是一个接口,但是它是一种特殊的接口:SAM类型的接口 ...

  8. java8新特性学习:stream与lambda

    Streams api 对 Stream 的使用就是实现一个 filter-map-reduce 过程,产生一个最终结果,或者导致一个副作用(side effect). 流的操作类型分为两种: Int ...

  9. es6新特性学习

    本文用来记录一下es6的新特性,持续更新.... es6在前端目前还不能大面试使用,包括移动端兼容也不好.不过在node中已可以使用其中96%的特性.也可使用一些插件将es6转化为es5,比如babl ...

随机推荐

  1. 【luogu P3379 最近公共祖先】 模板

    题目链接:https://www.luogu.org/problemnew/show/P3379 倍增求lca,先存下板子,留个坑以后再填讲解. in 5 5 43 12 45 11 42 43 23 ...

  2. android ListView 与GridView 学习总结(五)

    ListView的使用总结 基本使用:   步骤:在布局文件中定义一个ListView控件-在活动中获得ListView的实例-获得适配器adapter的实例并且传入三个参数-把适配器对象传递给lis ...

  3. Vue nodejs商城项目-商品列表页面组件

    data(){        return {            goodsList:[], // 商品列表            priceFilter:[ // 价格区间数组          ...

  4. SpringMVC 导入导出Excel文件

    /**  * 下载Excel模板 创建一个新的文件用于下载,创建的文件放在缓存中  *   * @param request  * @param response  */ /*  * @Request ...

  5. nodejs+express开发blog(2)

    npm install -g nodemon 1,把ejs文件修改为html文件 app.engine('.html', require('ejs').__express);app.set('view ...

  6. 【TOJ 1449】Area of Circles II(求不同位置的两圆面积之和)

    描述 There are two circles on the plane. Now you must to calculate the area which they cover the plane ...

  7. chrome浏览器中 F12 功能的简单介绍

    chrome浏览器中 F12 功能的简单介绍 由于F12是前端开发人员的利器,所以我自己也在不断摸索中,查看一些博客和资料后,自己总结了一下来帮助自己理解和记忆,也希望能帮到有需要的小伙伴,嘿嘿! 首 ...

  8. centos7 openvpn代理搭建

    系统环境:centos7.1 拨号ip地址:125.112.194.40(公网) server端部署 一.准备工作 1.检查SELinux状态,关闭 sed -i 's/enforcing/disab ...

  9. TCP回话劫持原理和利用

    由于 TCP 协议并没有对 TCP 的传输包进行身份验证,所以在我们知道一个 TCP 连接中的 seq 和 ack 的信息后就可以很容易的伪造传输包,假装任意一方与另一方进行通信,我们将这一过程称为 ...

  10. javascript--事件对象e的来源、意义、应用及其属性的用法 function(e){}

    在类似于arcgis api for javascript中,经常会遇到function(e),以前一直不懂e是个什么玩意,这种写法啥意思,经过最近一段时间学习,对e有了很深了解,本文通过各种示例,由 ...