Python中实现输入超时及如何通过变量获取变量名


Posted in Python onJanuary 18, 2020

背景介绍

开发中遇到了一个需求:程序运行到某处时需要用户确认, 但不能一直傻等, 后面的程序不能被一直阻塞, 需要有个超时限制, 也就是这个程序如果在一段时间后还没有得到用户输入就执行默认操作.

解决思路 ? 多线程法

我就想到了用多线程的方式, 开启一个子线程用stdin(比如python的input函数)获取用户输入, 主线程里设置线程启动和超时.

创建线程

Python中使用多线程很方便, threading.Threaded(函数, 参数表)然后thread.start就好了. 只是有一点需要注意, 上面参数表必须是个元组, 也就是每个元素后面必须跟个逗号.

import threading
def anyFunction(aaa):
 return str(aaa) #某种处理结果, 比如字符串
def manualInput(xxx):
 data = input("请输入%s: " % xxx)
 pass # 各种处理(比如数据转换什么的)
 
exampleThread = threading.Thread(target = manualInput, args = ( anyFunction("汪汪汪"), ), name = "喵喵喵")
exampleThread.start()

通过函数修改某个指定的(通过名字即字符串)变量的值
但这又出来一个问题, 如果不能使用全局变量, 该如何在另一个函数里修改其参数对应的内容呢? 这里的重点归结起来是"函数如何修改自身参数的内容".

于是我想到了一个骚透了的方法——改变量字典…… 因为python的变量是基于标签的. python中的变量大致可以理解成给内容贴上标签(每个标签对应一个变量名, 多个标签可能会引用同一个内容, 没被引用的内容就会被python释放), 每个标签都会有一个id(同时, 一个内存数据只要被引用那么自身也有个id). 示例:

print(id("喵喵喵"),"~~", id("喵喵喵"),"~~", id("喵喵喵"),"~~")
[Out]: 
1392371317520 ~~ 1392371317520 ~~ 1392371317520 ~~
print(id("喵喵喵")); print(id("喵喵喵")); print(id("喵喵喵"))
[Out]: 
1392371318576
1392371318000
1392371318288

python维护这些标签和内容的对应关系可以通过字典的方式来读取和修改, 改globals()[待改的变量的原名]的值就能通过指定变量名来修改变量了.

Python中实现输入超时及如何通过变量获取变量名

通过globals的字典修改变量

通过变量来获取变量的名字(字符串)
上面通过globals()[待改的变量的原名] = 新的内容的方式实现了修改变量的内容, 可是, 待改的变量的原名是个字符串, 怎么通过变量得到这个变量的名字呢?

一个思路是字典法.

把当前运行环境中的所有变量复制一份(浅拷贝和深拷贝效果都一样, 因为深浅拷贝前后都是相同的标签), 然后新建一个"标签id-变量名"的对照表字典, 利用字典赋值的特性, 遍历复制来的全局变量, 把id(变量值)作为key而变量名作为value, 即标签id-变量名字典[id(变量值)] = 变量名.

test = "some values"   
变量A = "汪汪汪" 
当前所有变量 = globals().copy()
print(当前所有变量)

[Out]:
{'__name__': '__main__',..., 'test': 'some values', '变量A': '汪汪汪'}

内容_变量名字符串对照表 = {} 
for 变量名, 变量值 in 当前所有变量.items():
 内容_变量名字符串对照表[id(变量值)] = 变量名
print(内容_变量名字符串对照表)

[Out]:
{2437914516272: '__name__',..., 2437948462576: 'test', 2437948432816:'变量A'}

这样一来就建立一个内容-变量名字符串的对照表, 又因为id(变量A) 和 id(变量A的值)是相等, 利用这个特性就能通过变量来取变量值了.

变量A的值 = 变量A
print(id(变量A的值)
[Out]:
2437948432816
内容_变量名字符串对照表[id(变量A的值)]
[Out]:
'变量A'

通过函数修改变量

上面这一堆头发就是为了动态、通用地修改变量, 封装成函数就能在任何地方调用和修改了.

def 一个实现变量修改函数(要改的变量, 提示语):
 当前所有变量 = globals().copy()
 变量id表 = {}
 for 变量名, 变量值 in 当前所有变量.items():
  变量id表[id(变量值)] = 变量名
 待改的变量的原名 = 变量id表[id(要改的变量)]
 新的内容 = str(input(提示语))
 if len(新的内容) > 0 :
  globals()[待改的变量的原名] = 新的内容
 return 待改的变量的原名
tmp = "汪汪汪"

一个实现变量修改函数(tmp, "请输入新值: ")

[Out]:
请输入新值: 喵喵喵
 'tmp'
print(tmp)
[Out]:
喵喵喵

总结(demo)[不想看中间过程的话可以直接看这]

import time, threading
# 这里的demo是为了通用化. 因为在一个线程中再嵌套另个线程的话, 嵌套的线程获取不到所有变量
class ThreadWithReturn(threading.Thread):
 def __init__( self, target = None, args = () ):
  super(ThreadWithReturn,self).__init__()
  self.func = target
  self.args = args
 def run(self):
  self.result = self.func(*self.args)
 def getResult(self):
  try:
   return self.result
  except Exception as errInfo:
   print("遇到错误: ", errInfo)
   return None
def 一个实现变量修改函数(要改的变量, 提示语):
 当前所有变量 = globals().copy()
 变量id表 = {}
 for 变量名, 变量值 in 当前所有变量.items():
  变量id表[id(变量值)] = 变量名
 try:
  待改的变量的原名 = 变量id表[id(要改的变量)]
 except KeyError:
  print("***debug: 在不同的线程中运行, 获取不到出入变量的名字")
  待改的变量的原名 = None
 新的内容 = str(input(提示语))
 if len(新的内容) > 0 :
  if 待改的变量的原名 != None:
   globals()[待改的变量的原名] = 新的内容
 else:
  新的内容 = None
 return [待改的变量的原名, 新的内容]
def Gexit():
 exitConfirm = "u"
 waitForConirm = ThreadWithReturn( target = 一个实现变量修改函数, args = (exitConfirm, "收到了退出信号, 默认30秒后退出, 是否现在退出呢? (Y/n) 请输入: ",) )
 waitForConirm.start()
 waitForConirm.join(30)
 try:
  exitConfirm = waitForConirm.getResult()[1]
  print("***debug, got:", exitConfirm)
 except Exception as errInfo:
  print("***debug:", errInfo)
  exitConfirm = "u"
 if exitConfirm == "u":
  print("等待超时, 开始退出流程...")
  exitConfirm = "Ytt"
 if exitConfirm == "Ytt" or exitConfirm == "Y":
  if exitConfirm == "Y":
   print("确认退出, 开始退出流程...")
   pass # 这里放程序退出逻辑
 if exitConfirm == "n":
  print("取消退出, 继续运行...")
  pass # 这里放继续运行的逻辑
 return 0
Thread_waitForExit = threading.Thread(target = Gexit, args = ())
Thread_waitForExit.start()
Thread_waitForExit.join(45)

总结

以上所述是小编给大家介绍的Python中实现输入超时及如何通过变量获取变量的名字,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
python正常时间和unix时间戳相互转换的方法
Apr 23 Python
python操作ie登陆土豆网的方法
May 09 Python
Python查询阿里巴巴关键字排名的方法
Jul 08 Python
Python实现将16进制字符串转化为ascii字符的方法分析
Jul 21 Python
python爬虫获取京东手机图片的图文教程
Dec 29 Python
python实现随机漫步算法
Aug 27 Python
小白入门篇使用Python搭建点击率预估模型
Oct 12 Python
Python3内置模块pprint让打印比print更美观详解
Jun 02 Python
对python中不同模块(函数、类、变量)的调用详解
Jul 16 Python
在自动化中用python实现键盘操作的方法详解
Jul 19 Python
jupyter notebook中美观显示矩阵实例
Apr 17 Python
pytorch cuda上tensor的定义 以及减少cpu的操作详解
Jun 23 Python
Pytorch 计算误判率,计算准确率,计算召回率的例子
Jan 18 #Python
python:目标检测模型预测准确度计算方式(基于IoU)
Jan 18 #Python
Python实现计算长方形面积(带参数函数demo)
Jan 18 #Python
python实现的Iou与Giou代码
Jan 18 #Python
Python 简单计算要求形状面积的实例
Jan 18 #Python
python实现用类读取文件数据并计算矩形面积
Jan 18 #Python
python不使用for计算两组、多个矩形两两间的iou方式
Jan 18 #Python
You might like
PHP4实际应用经验篇(8)
2006/10/09 PHP
比file_get_contents稳定的curl_get_contents分享
2012/01/11 PHP
php 获取本地IP代码
2013/06/23 PHP
php获取网页里所有图片并存入数组的方法
2015/04/06 PHP
php 实现进制相互转换
2016/04/07 PHP
php实现单笔转账到支付宝功能
2018/10/09 PHP
出现“不能执行已释放的Script代码”错误的原因及解决办法
2007/08/29 Javascript
Array.prototype.slice.apply的使用方法
2010/03/17 Javascript
轻松创建nodejs服务器(8):非阻塞是如何实现的
2014/12/18 NodeJs
JavaScript日期时间与时间戳的转换函数分享
2015/01/31 Javascript
微信小程序 省市区选择器实例详解(附源码下载)
2017/01/05 Javascript
原生js实现简单的模态框示例
2017/09/08 Javascript
JS+HTML实现的圆形可点击区域示例【3种方法】
2018/08/01 Javascript
微信小程序实现复选框效果
2018/12/28 Javascript
layer 关闭指定弹出层的例子
2019/09/25 Javascript
微信小程序实现左侧滑动导航栏
2020/04/08 Javascript
Node.js API详解之 string_decoder用法实例分析
2020/04/29 Javascript
解决Vue + Echarts 使用markLine标线(precision精度问题)
2020/07/20 Javascript
理解JavaScript中的对象
2020/08/25 Javascript
Python中的pack和unpack的使用
2018/03/12 Python
Django 使用Ajax进行前后台交互的示例讲解
2018/05/28 Python
Python在Matplotlib图中显示中文字体的操作方法
2019/07/29 Python
opencv3/C++实现视频背景去除建模(BSM)
2019/12/11 Python
python中使用you-get库批量在线下载bilibili视频的教程
2020/03/10 Python
GDAL 矢量属性数据修改方式(python)
2020/03/10 Python
Matplotlib animation模块实现动态图
2021/02/25 Python
Foreo国际站:Foreo International
2018/10/29 全球购物
应届毕业生个人自我评价
2013/09/20 职场文书
法学专业个人求职信
2013/09/26 职场文书
物业管理专业个人的自我评价
2013/11/19 职场文书
医学院学生的自我评价分享
2013/11/19 职场文书
聘用意向书范本
2014/04/01 职场文书
2014第二批党员干部对照“四风”找差距检查材料思想汇报
2014/09/18 职场文书
2014年大学生工作总结
2014/11/20 职场文书
php 文件上传至OSS及删除远程阿里云OSS文件
2021/07/04 PHP
多台电脑共享文件怎么设置?多台电脑共享文件操作教程
2022/04/08 数码科技