1、python全局變量相關概念及使用
來自菜鳥教程上的例子: http://www.runoob.com/python3/python3-function.html
一、python入參需要注意地方
a=1 def speak(a=None): if a is None: print('None') else: print(a) speak() None speak(a=a) 1 class A(): def talk(self,filename=''): if filename=='': filename='filename' print('take:',filename) return filename def see(self,filename=None): if filename is not None: a='a' print(a) elif filename is None: a='elif' print('a:',a) print('filename:',filename) def speak(self): a=self.talk();print('a:',a) print('-------------') self.see() print('-------------') print('a:',a) aa=A() aa.speak() take: filename a: filename ------------- a: elif filename: None ------------- a: filename class A(): def talk(self,filename=''): if filename=='': filename='filename' print('take:',filename) return filename def see(self,filename=None): if filename is not None: a='a' print('a:',a) elif filename is None: a='elif' print('a:',a) print('filename:',filename) def speak(self): a=self.talk();print('a:',a) print('-------------') self.see(filename=a) print('-------------') print('a:',a) aa=A() aa.speak() take: filename a: filename ------------- a: a ------------- a: filename
二、python中,程序的變量並不是在哪個位置都可以訪問的,訪問權限決定於這個變量在哪里賦值的。
變量的作用域決定了哪一部分程序可以訪問哪個特定的變量名稱。python的作用域一共有4中。分別是:
L(local)局部作用域;E(Enclosing)閉包函數外的函數中;G(Global)全局作用域;B(Built-in)內建作用域
# Python 中只有模塊(module),類(class)以及函數(def、lambda)才會引入新的作用域, # 其它的代碼塊(如 if/elif/else/、try/except、for/while等)是不會引入新的作用域的, # 也就是說這這些語句內定義的變量,外部也可以訪問, if True: msg='msg' print(msg) msg #如果將 msg_new 定義在函數中,則它就是局部變量,外部不能訪問: def test(): msg_new='msg_new' print(msg_new) Traceback (most recent call last): File "D:\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2862, in run_code exec(code_obj, self.user_global_ns, self.user_ns) File "<ipython-input-3-ac28ad2bc0fc>", line 4, in <module> print(msg_new) NameError: name 'msg_new' is not defined
二、全局變量和局部變量
定義在函數內部的變量擁有一個局部作用域,定義在函數外的擁有全局作用域。
局部變量只能在其被聲明的函數內部訪問,訪問結束后銷毀,而全局變量可以在整個程序范圍內訪問。
total=0 def sum(arg1,arg2): total=arg1+arg2 print(total) return total sum(10,10) print(total) 20 0 #函數sum內total=20變量銷毀掉,打印最初賦值全局變量,total=0,如果沒有total=0,則報錯
total=0 def sum(arg1,arg2): global total total=arg1+arg2 print(total) return total sum(10,10) print(total) 20 20
三、如果要修改嵌套作用域(enclosing 作用域,外層非全局作用域)中的變量,則需要nonlocal關鍵字,代碼如下,比較兩者區別。
def outer(): num=10 def inner(): num=100 print(num) inner() print(num) outer() 100 10 def outer(): num=10 def inner(): nonlocal num #nonlocal關鍵字聲明 num=100 print(num) inner() print(num) outer() 100 100 #從上面代碼10 變為100
2、什么是回調函數,感覺好復雜??存在的意義是什么?
1、知乎上的回答:https://www.zhihu.com/question/19801131
你到一個商店買東西,剛好你要的東西沒有貨,於是你在店員那里留下了你的電話,過了幾天店里有貨了,店員就打了你的電話,然后你接到電話后就到店里去取了貨。在這個例子里,你的電話號碼就叫回調函數,你把電話留給店員就叫登記回調函數,店里后來有貨了叫做觸發了回調關聯的事件,店員給你打電話叫做調用回調函數,你到店里去取貨叫做響應回調事件。回答完畢。
2、什么是回調:http://www.jb51.net/article/68797.htm
軟件模塊之間總是存在着一定的接口,從調用方式上,可以把他們分為三類:同步調用、回調和異步調用。
同步調用是一種阻塞式調用,調用方要等待對方執行完畢才返回,它是一種單向調用;
回調是一種雙向調用模式,也就是說,被調用方在接口被調用時也會調用對方的接口;
異步調用是一種類似消息或事件的機制,不過它的調用方向剛好相反,接口的服務在收到某種訊息或發生某種事件時,會主動通知客戶方(即調用客戶方的接口)。
回調和異步調用的關系非常緊密,通常我們使用回調來實現異步消息的注冊,通過異步調用來實現消息的通知。
同步調用時三者中最簡單的,而回調又常常是異步調用的基礎。
回調函數:通過函數指針調用的函數。如果你把函數的指針(地址)作為參數傳遞給另一個函數,當這個指針被用來調用其所指向的函數時,我們就說這是回調函數。如下面的例子1:來源 https://www.cnblogs.com/hainan-zhang/p/6222552.html
下面例子:我猜測函數指針應該為function_name
def clean1(times): """ 就假裝掃地 param times :次數 return None """ print('已完成掃地次數:',times) def clean2(times): """ 假裝洗抽油煙機 param times:次數 return: None """ print('已洗抽油煙機次數:',times) def call_clean(times,function_name): """ 這個很重要,就是家政公司的業務系統,要啥業務都得在這說 這個是實現回調函數的核心 param times:次數 param function_name:回調函數名 return:調用的函數結果 """ return function_name(times) call_clean(10,clean2) #call_clean(10,clean2)
這個例子介紹回調函數的使用,沒有說明回調函數存在的意義?這樣寫還不如直接調用clean2函數10次。
下面在網上找的另外一個,例子2:http://blog.csdn.net/ma52103231/article/details/61432120
看着有點懵,難度大,換一個
class Callback: def __init__(self,instance,function_name): self.instance=instance self.function_name=function_name def action(self,params): self.instance.__getattribute__(self.function_name)(params) class Test: def __init__(self): self.clb=None def register(self,clb): self.clb=clb def do_test(self): params=[] self.clb.action(params) class Api: def __init__(self,test_instance): test_instance.register(Callback(self,self.function.__name__)) def function(self,params): print('function') t=Test() a=Api(t) t.do_test() #function
例子3:http://blog.csdn.net/ma52103231/article/details/61432120
#called.py文件,為回調函數 def test_call(p_call): print('in called.py test_call()') b=p_call() return b ###call.py文件,主程序 import called def callback(): a=1 b=a+1 print('in callback') return b def main(): global x #called.test() x=called.test_call(callback) print('in call.py') main() print(x) 運行主程序結果: in called.py test_call() in callback in call.py 2
3、一個主程序腳本文件,main.py,一個回調函數腳本文件,pyCallBack.py,main.py調用pyCallBack.py,在回調函數中生成數據,現在想把數據傳到主程序上來,該如何寫?
解答:可以用return直接返回即可。如上面例子3