一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Python中實現輸入超時及如何通過變量獲取變量名

Python中實現輸入超時及如何通過變量獲取變量名

2020-04-15 09:56佚之狗 Python

這篇文章主要介紹了Python中實現輸入超時以及通過變量獲取變量的名字,本文給大家分享了解決思路主要是通過多線程法實現,需要的朋友可以參考下

背景介紹

開發中遇到了一個需求:程序運行到某處時需要用戶確認, 但不能一直傻等, 后面的程序不能被一直阻塞, 需要有個超時限制, 也就是這個程序如果在一段時間后還沒有得到用戶輸入就執行默認操作.

解決思路 – 多線程法

我就想到了用多線程的方式, 開啟一個子線程用stdin(比如python的input函數)獲取用戶輸入, 主線程里設置線程啟動和超時.

創建線程

Python中使用多線程很方便, threading.Threaded(函數, 參數表)然后thread.start就好了. 只是有一點需要注意, 上面參數表必須是個元組, 也就是每個元素后面必須跟個逗號.

?
1
2
3
4
5
6
7
8
9
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). 示例:

?
1
2
3
4
5
6
7
8
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(變量值)] = 變量名.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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的值)是相等, 利用這個特性就能通過變量來取變量值了.

?
1
2
3
4
5
6
7
變量A的值 = 變量A
print(id(變量A的值)
[Out]:
2437948432816
內容_變量名字符串對照表[id(變量A的值)]
[Out]:
'變量A'

通過函數修改變量

上面這一堆頭發就是為了動態、通用地修改變量, 封裝成函數就能在任何地方調用和修改了.

?
1
2
3
4
5
6
7
8
9
10
11
def 一個實現變量修改函數(要改的變量, 提示語):
 當前所有變量 = globals().copy()
 變量id= {}
 for 變量名, 變量值 in 當前所有變量.items():
  變量id表[id(變量值)] = 變量名
 待改的變量的原名 = 變量id表[id(要改的變量)]
 新的內容 = str(input(提示語))
 if len(新的內容) > 0 :
  globals()[待改的變量的原名] = 新的內容
 return 待改的變量的原名
tmp = "汪汪汪"

一個實現變量修改函數(tmp, "請輸入新值: ")

 

?
1
2
3
4
5
6
[Out]:
請輸入新值: 喵喵喵
 'tmp'
print(tmp)
[Out]:
喵喵喵

 

總結(demo)[不想看中間過程的話可以直接看這]

?
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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中實現輸入超時及如何通過變量獲取變量的名字,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!

原文鏈接:https://blog.csdn.net/qq_39707057/article/details/104002512

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 掰开逼操 | 免费观看韩剧网站在线观看 | 超碰成人在线播放 | 啊好大好粗 | 天堂成人在线观看 | 国产成人精品系列在线观看 | 精品午夜中文字幕熟女人妻在线 | 视频一本大道香蕉久在线播放 | 久久精品小视频 | 污污美女| 女子校生下媚药在线观看 | 欧美猛男同志同性video | 日本精品一区二区在线播放 | wwwav在线| 91系列在线观看免费 | 4455四色永久免费 | 男同gay作爰视频网站 | 国内亚州视频在线观看 | 亚洲国产精品一区二区久久 | 国产在线欧美精品 | 亚洲人成网站在线观看妞妞网 | 国产新疆成人a一片在线观看 | 欧美在线视频免费播放 | 小早川怜子在线播放精品 | 天天操天天射天天色 | 欧美日韩在线观看精品 | 丝瓜污污| 日本精工厂网址 | 我的家教老师 | 青草免费在线观看 | 欧美日韩亚洲另类人人澡 | 成人综合网站 | 色综色| 香蕉成人国产精品免费看网站 | 国产主播精品在线 | 成人在线视频国产 | 色多多影院 | 6080窝窝理论 | 国产成人盗摄精品 | 91精品国产亚洲爽啪在线影院 | 男人疯狂擦进女人下面 |