Python基础:全局编译器和解释器的区别所GIL,

  Python中的进程线程(二)
一、python中的“锁”
1.GIL锁(全局解释锁)
Python中的线程是操作系统的原生线程,Python虚拟机使用一个全局解释器锁(Global Interpreter Lock)来互斥线程对Python虚拟机的使用。为了支持多线程机制,一个基本的要求就是需要实现不同线程对共享资源访问的互斥,所以引入了GIL。GIL:在一个线程拥有了解释器的访问权之后,其他的所有线程都必须等待它释放解释器的访问权,即使这些线程的下一条指令并不会互相影响。在调用任何Python C API之前,要先获得GIL。GIL缺点:多处理器退化为单处理器;优点:避免大量的加锁解锁操作。
1.1GIL的影响
无论你启多少个线程,你有多少个cpu, Python在执行一个进程的时候会淡定的在同一时刻只允许一个线程运行。所以,python是无法利用多核CPU实现多线程的。这样,python对于计算密集型的任务开多线程的效率甚至不如串行(没有大量切换),但是,对于IO密集型的任务效率还是有显著提升的。
IO密集型案例:IO密集型即线程中存在大量的IO操作。
import threadingimport timedef foo(n):
  time.sleep(n)
  print("foo....%s" % n)
  print(threading.activeCount())
def bar(n):
  time.sleep(n)
  print("bar......%s" % n)
s=time.time()t1=threading.Thread(target=foo,args=(2,))#t1.setDaemon(True)t1.start()
t2=threading.Thread(target=bar,args=(5,))#t2.setDaemon(True)t2.start()
# 阻塞主线程t2.join()
print("++++++",threading.activeCount())print("ending!")print("cost time:",time.time()-s)
计算密集型案例:
import threading
import time
def foo(n):
  for i in range(n):
    ret+=i
  print(ret)
def bar(n):#计算密集型的任务指的是线程中存在大量的计算任务我们以阶乘和累加为例,通过传统的串行执行函数和计算。
  for i in range(1,n):
    ret*=i
  print(ret)
s=time.time()t1=threading.Thread(target=foo,args=(,))t1.start()t2=threading.Thread(target=bar,args=(100000,))t2.start()t1.join()t2.join()print("cost time:",time.time()-s)
import threading
import time
def sub():
  global num # 掌握为什么加global num,在每个线程中都获取这个全局变量
  lock.acquire()#加锁操作,
  temp=num
  time.sleep(0.1 )
  num=temp-1# 对此公共变量进行-1操作
  lock.release()#解锁操作
time.sleep(2)
lock=threading.Lock()
for i in range(100):
t=threading.Thread(target=sub,args=())
l.append(t)
for t in l:
  t.join()#等待所有线程运行完毕。
print(num)
锁通常被用来实现对共享资源的同步访问。为每一个共享资源创建一个Lock对象,当你需要访问该资源时,调用acquire方法来获取锁对象(如果其它线程已经获得了该锁,则当前线程需等待其被释放),待资源访问完后,再调用release方法释放锁。
3.死锁与递归锁
所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
import threadingimport time
mutexA = threading.Lock()mutexB = threading.Lock()
class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
self.fun1()
self.fun2()
def fun1(self):
mutexA.acquire()
# 如果锁被占用,则阻塞在这里,等待锁的释放
print ("I am %s , get res: %s---%s" %(self.name, "ResA",time.time()))
mutexB.acquire()
print ("I am %s , get res: %s---%s" %(self.name, "ResB",time.time()))
mutexB.release()
mutexA.release()
def fun2(self):
mutexB.acquire()
print ("I am %s , get res: %s---%s" %(self.name, "ResB",time.time()))
time.sleep(0.2)
mutexA.acquire()
print ("I am %s , get res: %s---%s" %(self.name, "ResA",time.time()))
mutexA.release()
mutexB.release()
if __name__ == "__main__":
print("start---------------------------%s"%time.time())
for i in range(0, 10):
my_thread = MyThread()
my_thread.start()
在Python中为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock。这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。上面的例子如果使用RLock代替Lock,则不会发生死锁:
Rlock=threading.RLock()
二.Event对象
线程的一个关键特性是每个线程都是独立运行且状态不可预测。如果程序中的其 他线程需要通过判断某个线程的状态来确定自己下一步的操作,这时线程同步问题就 会变得非常棘手。为了解决这些问题,我们需要使用threading库中的Event对象。 对象包含一个可由线程设置的信号标志,它允许线程等待某些事件的发生。在 初始情况下,Event对象中的信号标志被设置为假。如果有线程等待一个Event对象, 而这个Event对象的标志为假,那么这个线程将会被一直阻塞直至该标志为真。一个线程如果将一个Event对象的信号标志设置为真,它将唤醒所有等待这个Event对象的线程。如果一个线程等待一个已经被设置为真的Event对象,那么它将忽略这个事件, 继续执行。
主要执行的方法有:
Event.wait([timeout]) : 堵塞线程,直到Event对象内部标识位被设为True或超时(如果提供了参数timeout)。
Event.set() :将标识位设为Ture
Event.clear() : 将标识伴设为False。
Event.isSet() :判断标识位是否为Ture。
代码示例:模拟红绿灯
设计一个关于红绿灯的线程,5个关于车的线程;对于车线程,每隔一个随机秒数,判断红绿灯的状态,是红灯或者黄灯,打印waiting;是绿灯打印running。对于红绿灯线程:
首先默认是绿灯,做一个计数器,十秒前,每隔一秒打印“light green”;第十秒到第十三秒,每隔一秒打印“light yellow”,13秒到20秒,
‘light red’,20秒以后计数器清零。重新循环。知识点:event对象(提示:event对象即红绿灯,为true是即绿灯,false时为黄灯或者红灯)
import threadingimport timeimport random
event=threading.Event()def light():
while True:
if count&10:
event.set()
time.sleep(1)
print('\033[32m light green.....\033[0m')
elif 10 & count &13:
event.clear()
time.sleep(1)
print('\033[33m light yellow....\033[0m')
elif 13 & count &20:
event.clear()
time.sleep(1)
print('\033[31m light
red .....\033[0m')
elif count &20:
count +=1def car():
while True:
r=random.randint(1,3)
time.sleep(r)
if event.is_set():
print("car is running.....")
elif not event.is_set():
print("car is waiting....")lig=threading.Thread(target=light,args=())lig.start()for i in range(5):
ca=threading.Thread(target=car,args=())
ca.start()
三.信号量(Semaphore)
Semaphore管理一个内置的计数器,每当调用acquire()时内置计数器-1;调用release() 时内置计数器+1;计数器不能小于0;当计数器为0时,acquire()将阻塞线程直到其他线程调用release()。
实例:(同时只有5个线程可以获得semaphore,即可以限制最大连接数为5):
import threading
import time
semaphore = threading.Semaphore(5)
def func():
if semaphore.acquire():
print (threading.currentThread().getName() + ' get semaphore')
time.sleep(2)
semaphore.release()
for i in range(20):
t1 = threading.Thread(target=func)
t1.start()
创建一个“队列”对象
import Queueq = Queue.Queue(maxsize = 10)Queue.Queue类即是一个队列的同步实现。队列长度可为无限或者有限。可通过Queue的构造函数的可选参数maxsize来设定队列长度。如果maxsize小于1就表示队列长度无限。
将一个值放入队列中q.put(10)调用队列对象的put()方法在队尾插入一个项目。put()有两个参数,第一个item为必需的,为插入项目的值;第二个block为可选参数,默认为1。如果队列当前为空且block为1,put()方法就使调用线程暂停,直到空出一个数据单元。如果block为0,put方法将引发Full异常。
将一个值从队列中取出q.get()调用队列对象的get()方法从队头删除并返回一个项目。可选参数为block,默认为True。如果队列为空且block为True,get()就使调用线程暂停,直至有项目可用。如果队列为空且block为False,队列将引发Empty异常。
队列方法:
'''join() 阻塞进程,直到所有任务完成,需要配合另一个方法task_done。
def join(self):
with self.all_tasks_done:
while self.unfinished_tasks:
self.all_tasks_done.wait()
task_done() 表示某个任务完成。每一条get语句后需要一条task_done。
import queueq = queue.Queue(5)q.put(10)q.put(20)print(q.get())q.task_done()print(q.get())q.task_done()
print("ending!")
其他常用方法:
此包中的常用方法(q = Queue.Queue()):
q.qsize() 返回队列的大小q.empty() 如果队列为空,返回True,反之Falseq.full() 如果队列满了,返回True,反之Falseq.full 与 maxsize 大小对应q.get([block[, timeout]]) 获取队列,timeout等待时间q.get_nowait() 相当q.get(False)非阻塞 q.put(item) 写入队列,timeout等待时间q.put_nowait(item) 相当q.put(item, False)q.task_done() 在完成一项工作之后,q.task_done() 函数向任务已经完成的队列发送一个信号q.join() 实际上意味着等到队列为空,再执行别的操作
其他的模式
Python Queue模块有三种队列及构造函数:
1、Python Queue模块的FIFO队列先进先出。 class queue.Queue(maxsize) 2、LIFO类似于堆,即先进后出。
class queue.LifoQueue(maxsize) 3、还有一种是优先级队列级别越低越先出来。 class queue.PriorityQueue(maxsize)
import queue
q=queue.LifoQueue()
q.put(34)q.put(56)q.put(12)
#优先级q=queue.PriorityQueue()q.put([5,100])q.put([7,200])q.put([3,"hello"])q.put([4,{"name":"alex"}])
data=q.get()
print(data)
2.生产者消费者模型
在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
这就像,在餐厅,厨师做好菜,不需要直接和客户交流,而是交给前台,而客户去饭菜也不需要不找厨师,直接去前台领取即可,这也是一个结耦的过程。
import threadingimport randomimport queueimport timeq=queue.Queue(20)def Producer():#生产者负责生产数据
while count &10:
# if q.qsize()&20:
s=random.randint(1,100)
print("has mod baozi %s"%s)
time.sleep(5)
count+=1def Consumer(id):#消费者负责取数据。
while True:
print("Consumer"+id+"has eat %s "%s)
time.sleep(5)for i in range(50):
t1= threading.Thread(target=Producer,args=())
t1.start()for i in
range(10):
t=threading.Thread(target=Consumer,args=(str(i),))
阅读(...) 评论()您所在的位置: &
线程和全局解释器锁(GIL)
线程和全局解释器锁(GIL)
[美] Wesley J. Chun著/宋吉广译
人民邮电出版社
《Python核心编程》(中文第二版)第22章主要讲的是扩展Python,讨论如何编写扩展代码并将它们的功能整合到Python编程环境中来。本节为您介绍的是线程和全局解释器锁(GIL)。
22.2.6& 线程和全局解释器锁(GIL)
编译扩展的人必须要注意,他们的代码有可能会被运行在一个多线程的Python环境中。早在18.3.1节,我们就介绍了Python虚拟机(PVM)和全局解释器锁(GIL),并描述了在PVM中,任何情况下同时只会有一个线程被运行,其他线程会被GIL停下来。而且,我们指出调用扩展代码等外部函数时,代码会被GIL锁住,直到函数返回为止。
前面我们也提到过一种折衷方案,可以让编写扩展的程序员释放GIL,例如在系统调用前就可以做到。这是通过将你的代码和线程隔离实现的,这些线程使用了另外两个C宏Py_BEGIN_ALLOW_ THREADS和Py_END_ALLOW_THREADS,保证了运行和非运行时的安全性。由这些宏包裹的代码将会允许其他线程的运行。
同引用计数宏一样,我们强烈建议阅读关于扩展和嵌入Python的文档和Python/C API参考手册。
【责任编辑: TEL:(010)】 &&&&&&
关于&&&&&&&&的更多文章
掌握Android Wear平台,加入可穿戴革命
可穿戴是移动技术的下一
本书描述了黑客用默默无闻的行动为数字世界照亮了一条道路的故事。
讲师: 23人学习过讲师: 42人学习过讲师: 74人学习过
《21天学通Visual C++(第4版)》共21章,从Visual C+
《21天学通Python》全面、系统、深入地讲解了Python编
《21天学通C语言(第4版)》是C语言的入门教程,详细
本书是在第1版的基础上全面更新、改版而成的,仍然是目前图书市场中唯一一本全面介绍硬件服务器的IT图书。本书针对近两年来所出
51CTO旗下网站用户名:lilongzi007
文章数:75
评论数:27
访问量:39522
注册日期:
阅读量:1297
阅读量:3317
阅读量:588259
阅读量:474821
51CTO推荐博文
Python介绍&Python是由创始人吉多?范罗苏姆(Guido van Rossum)在1989年圣诞节假期期间,为了打发时间,构思出来的一个新的脚本解释器。由于Guido在开发Python语言过程中,借鉴了很多ABC语言特性,所有后来包括Guido自己也那么认为,Python语言的前身就是ABC语言。&Python是一门面向对象的、动态解释型强定义语言;Python崇尚简洁、优美、清晰,是一门优秀的被广泛使用的语言。&在2015年以前,最流行的Python版本还是2.4,但是由于Python官方在2008年发布了3.0,一是款完全不同的Python版本,不兼容包括2.4在内以前的的任何版本,这就影响了3.0的推行,才出了一个既可以兼容2.4又支持很多3.0新特性的2.6版本。官方还开发了专门的帮助将2.x转为3.0版本的转换工具,因此,python3.0的使用才开始逐渐多了起来。&&Python应用领域云计算:Openstack自动化:Saltstack、Ansible系统运维:运维人员必会的语言图形:PyQT, WxPython,TkInteWeb开发:众多大型网站都是基于Python开发,如Youtube 典型的Web框架有Django科学运算:人工智能如AlphaGo、典型库NumPy, SciPy, Matplotlib, Enthought librarys,pandas金融行业:在金融工程领域,作为动态语言的Python,语言结构清晰简单,库丰富,成熟稳定,科学计算和统计分析都很牛逼,生产效率远远高于c,c++,java,尤其擅长策略回测&&Python特点优点1)Python的定位是“优雅”、“明确”、“简单”,所以Python程序看上去总是简单易懂,初学者学Python,不但入门容易,而且将来深入下去,可以编写那些非常非常复杂的程序。2)开发效率非常高,Python有非常强大的第三方库,基本上你想通过计算机实现任何功能,Python官方库里都有相应的模块进行支持,直接下载调用后,在基础库的基础上再进行开发,大大降低开发周期,避免重复造轮子。3)高级语言:当你用Python语言编写程序的时候,你无需考虑诸如如何管理你的程序使用的内存一类的底层细节4)可移植性:由于它的开源本质,Python已经被移植在许多平台上(经过改动使它能够工 作在不同平台上)。如果你小心地避免使用依赖于系统的特性,那么你的所有Python程序无需修改就几乎可以在市场上所有的系统平台上运行5)可扩展性:如果你需要你的一段关键代码运行得更快或者希望某些算法不公开,你可以把你的部分程序用C或C++编写,然后在你的Python程序中使用它们。6)可嵌入性:你可以把Python嵌入你的C/C++程序,从而向你的程序用户提供脚本功能。缺点1)速度慢:由于天生就是一门解释型语言,Python和C、JAVA对比的话,运行速度是会慢很多,适合对一些网页脚本、服务器脚本及辅助开发接口这样的对速度要求不高、对不同系统平台间的兼容性有一定要求的程序;不适合对速度要求极高的搜索引擎等程序。2)代码不能加密:如果你的项目源代码要求加密,那么不适合用Python开发3)线程不能利用多CPU:这是Python被人诟病最多的一个缺点,GIL即全局解释器锁(Global Interpreter Lock),是计算机程序设计语言解释器用于同步线程的工具,使得任何时刻仅有一个线程在执行,Python的线程是操作系统的原生线程。在Linux上为pthread,在Windows上为Win thread,完全由操作系统调度线程的执行。一个python解释器进程内有一条主线程,以及多条用户程序的执行线程。即使在多核CPU平台上,由于GIL的存在,所以禁止多线程的并行执行& &Python的安装1)windows官方网站提供了默认的下载渠道:&截止到现在,最多的还是3.5版本,不过要注意区分平台:Windows、Mac、Linux建议同时下载安装两个版本,分别放在C:\Python2.7和C:\Python3.5, 方便对一些程序特性做测试注意修改环境变量:右键计算机--&属性--&高级系统设置--&环境变量--&找到变量名为Path的一行双击--&Python安装目录追加到变量值中,用分号;分割。&&2)LinuxLinux Centos 7 中是将Python作为默认软件安装的,只不过具体OS版本不同[root@linux-node1&~]#&python
python&&&&&python2&&&&python2.7&#centos7中默认为2.7版本我们只需要下载并安装3.5版本就可以了,下载地址:tar&xf&Python-3.5.2.tar.xz
cd&Python-3.5.2/
./configure
make&&&&make&install修改系统默认的Python版本[root@linux-node1&Python-3.5.2]#&mv&/usr/bin/python&/usr/bin/python2.ori
[root@linux-node1&Python-3.5.2]#&ln&-s&/usr/local/bin/python3.5&/usr/bin/python为了防止修改完Python版本后yum出问题,需修改yumvim&/usr/bin/yum
#!/usr/bin/python&&#修改为/usr/bin/python2.ori&3)Mac直接下载运行即可Max&Os&X 10.5:Max&Os&X 10.6:lichengbing:~&$&python3
Python&3.5.2&(v3.5.2:4def2a2901a5,&Jun&26&:25)
[GCC&4.2.1&(Apple&Inc.&build&5666)&(dot&3)]&on&darwin
Type&"help",&"copyright",&"credits"&or&"license"&for&more&information.
&&&&&Python开发环境【Pycharm】For Windows下载地址:&&Python快速入门1)我的第一个Python程序“Hello World!”[root@linux-node1&~]#&vim&hello.py
#!/usr/bin/env&python
print("Hello&World!")
[root@linux-node1&~]#&./hello.py&#&.执行文件需要给文件添加x权限
Hello&World&&2)变量和字符编码python解释器在加载 .py 文件中的代码时,会对内容进行编码(默认ascillASCII(American Standard Code for InformationInterchange,美国标准信息交换代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言,其最多只能用 8 位来表示(一个字节),即:2**8 = 256-1,所以,ASCII码最多只能表示 255 个符号。&显然ASCII码无法将世界上的各种文字和符号全部表示,所以,就需要新出一种可以代表所有字符和符号的编码,即:Unicode Unicode(万国码)是一种在计算机上使用的字符编码。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,规定虽有的字符和符号最少由 16 位来表示(2个字节),即:2 **16 = 65536.&UTF-8,是对Unicode编码的压缩和优化,他不再使用最少使用2个字节,而是将所有的字符和符号进行分类:ascii码中的内容用1个字节保存、欧洲的字符用2个字节保存,东亚的字符用3个字节保存...所以,python解释器在加载 .py 文件中的代码时,会对内容进行编码(默认ascill)#!/usr/bin/env&python&#设置脚本系统环境变量
&#&-*-&coding:utf-8&-*-&#Python3.0版以上默认字符集为UTF-8,可以支持中文显示
&name&=&"lichengbing"
&print(name,age)& &3)注释'''&&
name&=&"lichengbing"&#&This&is&a&variable&
age&=&21&print(name,age)&
#注释最好不超过80个字符& &4)用户输入C:\Users\lilongzi&python2
Python&2.7.12&(v2.7.12:d33e0cf91556,&Jun&27&:40)&[MSC&v.1500&64&bit&(AMD64)]&on&win32
Type&"help",&"copyright",&"credits"&or&"license"&for&more&information.
&&&&user_name&=&raw_input("you&name:")
you&name:lichengbing
&&&&print(user_name)
lichengbing格式化用户输入name&=&input("input&you&name:")
age&=&int(input("input&you&age:"))
job&=&input("input&you&job:")
Infomation&of&user&name:%s:
--------------
------END-----
'''&%&(name,name,age,job)
print(msg)执行结果input&you&name:lichengbing
input&you&age:25
input&you&job:ENGINEER
Infomation&of&user&name:lichengbing:
--------------
Name:&&lichengbing
Job:&&&ENGINEER
------END-----用户输入密码隐藏import&getpass
username&=&input("uesrname:")
password&=&getpass.getpass("password:")
print(username,password)
#只支持在Linux环境下用Python3执行&&5)初识模块调用系统命令[root@linux-node1&~]#&python
Python&2.7.5&(default,&Nov&20&:19)
[GCC&4.8.5&&(Red&Hat&4.8.5-4)]&on&linux2
Type&"help",&"copyright",&"credits"&or&"license"&for&more&information.
&&&&import&os
&&&&os.system("df&-h")
Filesystem&&&&&&Size&&Used&Avail&Use%&Mounted&on
/dev/sda3&&&&&&&9.0G&&5.1G&&4.0G&&56%&/
devtmpfs&&&&&&&&480M&&&&&0&&480M&&&0%&/dev
tmpfs&&&&&&&&&&&489M&&&&&0&&489M&&&0%&/dev/shm
tmpfs&&&&&&&&&&&489M&&&19M&&470M&&&4%&/run
tmpfs&&&&&&&&&&&489M&&&&&0&&489M&&&0%&/sys/fs/cgroup
/dev/sda1&&&&&&&253M&&111M&&143M&&44%&/boot
tmpfs&&&&&&&&&&&&98M&&&&&0&&&98M&&&0%&/run/user/0
0保存调用的命令并定义为变量&&&&cmd_res&=&os.popen("df&-h").read()
&&&&print(cmd_res)
Filesystem&&&&&&Size&&Used&Avail&Use%&Mounted&on
/dev/sda3&&&&&&&9.0G&&5.1G&&4.0G&&56%&/
devtmpfs&&&&&&&&480M&&&&&0&&480M&&&0%&/dev
tmpfs&&&&&&&&&&&489M&&&&&0&&489M&&&0%&/dev/shm
tmpfs&&&&&&&&&&&489M&&&20M&&470M&&&4%&/run
tmpfs&&&&&&&&&&&489M&&&&&0&&489M&&&0%&/sys/fs/cgroup
/dev/sda1&&&&&&&253M&&111M&&143M&&44%&/boot
tmpfs&&&&&&&&&&&&98M&&&&&0&&&98M&&&0%&/run/user/0Python全局环境变量&&&&import&sys
&&&&print(sys.path)
['',&'/usr/lib64/python27.zip',&'/usr/lib64/python2.7',&'/usr/lib64/python2.7/plat-linux2',&'/usr/lib64/python2.7/lib-tk',&'/usr/lib64/python2.7/lib-old',&'/usr/lib64/python2.7/lib-dynload',&'/usr/lib64/python2.7/site-packages',&'/usr/lib64/python2.7/site-packages/gtk-2.0',&'/usr/lib/python2.7/site-packages']将tab.py放入环境变量中,Python在导入os等模块后能自动补全命令[root@linux-node1&site-packages]#&pwd
/usr/lib64/python2.7/site-packages
#!/usr/bin/env&python
#&python&startup&file
import&sys
import&readline
import&rlcompleter
import&atexit
#&tab&completion
readline.parse_and_bind('tab:&complete')
#&history&file
histfile&=&os.path.join(os.environ['HOME'],&'.pythonhistory')
&&&&readline.read_history_file(histfile)
except&IOError:
atexit.register(readline.write_history_file,&histfile)
del&os,&histfile,&readline,&rlcompleter查看自动补全&&&&import&tab
&&&&import&os
Display&all&249&possibilities?&(y&or&n)
os.EX_CANTCREAT&&&&&&&&&&&&&os.__package__&&&&&&&&&&&&&&os.listdir(
os.EX_CONFIG&&&&&&&&&&&&&&&&os.__reduce__(&&&&&&&&&&&&&&os.lseek(&6)if条件判断if判断age&=&22
guess_number&=&int(input("input&you&guess&number:"))
if&guess_number&==&age&:
&&&&print("Congratulations!")
elif&guess_number&&&age&:
&&&&print("Think&smaller...")
print("Think&larger...")跳出循环age&=&22
for&i&in&range(10):
&&&&guess_number&=&int(input("input&you&guess&number:"))
&&&&if&guess_number&==&age&:
&&&&&&&&print("Congratulations!")
&&&&&&&&break
&&&&elif&guess_number&&&age&:
&&&&&&&&print("Think&smaller...")
&&&&else&:
&&&&&&&&print("Think&larger...")简单的猜数字游戏age&=&22
counter&=&0
for&i&in&range(10):
&&&&if&counter&&3:
&&&&&&&&guess_number&=&int(input("input&you&guess&number:"))
&&&&&&&&if&guess_number&==&age&:
&&&&&&&&&&&&print("Congratulations!")
&&&&&&&&&&&&break
&&&&&&&&elif&guess_number&&&age&:
&&&&&&&&&&&&print("Think&smaller...")
&&&&&&&&else&:
&&&&&&&&&&&&print("Think&larger...")
&&&&&&&&#print("Too&namy&attempts...bye!")
&&&&&&&&#break
&&&&&&&&continue_confirm&=&input("Do&you&want&to&continue&guess?&Y&or&N:&")
&&&&&&&&if&continue_confirm&==&'Y':
&&&&&&&&&&&&counter&=&0
&&&&&&&&&&&&continue
&&&&&&&&else:
&&&&&&&&&&&&print("bye...")
&&&&&&&&&&&&break
&&&&counter&+=&1input&you&guess&number:21
Think&smaller...
input&you&guess&number:25
Think&larger...
input&you&guess&number:1
Think&smaller...
Do&you&want&to&continue&guess?&Y&or&N:&Y
input&you&guess&number:&本文出自 “” 博客,请务必保留此出处
了这篇文章
类别:┆阅读(0)┆评论(0)}

我要回帖

更多关于 编译器和解释器的区别 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信