<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          四個函數(shù)搞清 Python 作用域

          共 5031字,需瀏覽 11分鐘

           ·

          2021-07-12 10:15

          ↑↑↑關(guān)注后"星標(biāo)"簡說Python

          人人都可以簡單入門Python、爬蟲、數(shù)據(jù)分析
           簡說Python推薦 

          來源: 簡說Python

          作者:鞏慶奎

          四個函數(shù)搞清 Python 作用域


          Python 內(nèi)置函數(shù)中,和作用域相關(guān)的函數(shù)有 locals、global、vars 以及 dir。日常常用這些函數(shù),但時常分不清準(zhǔn)確用法,試來試去。下面來分析這些函數(shù)是什么意思,有什么差別,一勞永逸學(xué)會 Python 作用域的相關(guān)知識點。

          本文先說明這些函數(shù)最直接的功能,然后對特殊情況進(jìn)行解釋,最后說明這些函數(shù)有什么用。

          最直接的功能

          最直接和常用的功能如下:

          • locals() 返回當(dāng)前局部作用域的符號表字典。
          • globals() 返回全局作用域的符號表字典。
          • vars() 相當(dāng)于 locals ()
          • dir() 返回當(dāng)前局部作用域的符號表字典對應(yīng)的 keys()。

          來看代碼。

          >>> import time
          >>> pi = 3.1415
          >>> globals()
          {'__spec__': None, 'pi': 3.1415, 'time': <module 'time' (built-in)>, '__loader__': <class'_frozen_importlib.BuiltinImporter'>, '__name__''__main__''__doc__': None, '__package__': None, '__builtins__': <module 'builtins' (built-in)>}

          這里導(dǎo)入了 time 模塊,定義了 pi 全局變量。調(diào)用 globas () 輸出全局變量,可見是一些系統(tǒng)相關(guān)的內(nèi)置屬性,以及定義的 pi 和導(dǎo)入的 time 。

          出于篇幅和方便閱讀考慮,之后輸出都不再列出 __ 開頭的屬性。上例輸出,去掉 __ 開頭屬性為:{'pi': 3.1415, 'time': <module 'time' (built-in)>},閱讀更清晰。

          繼續(xù)調(diào)用 locals() 函數(shù),輸出當(dāng)前局部作用域的變量表。因為 locals() 位于交互 REPL 界面,所以當(dāng)前局部作用域?qū)嶋H就是全局作用域,所以兩者輸出一樣。

          >>> locals() #去掉 __ 開頭的屬性。
          {'pi': 3.1415, 'time': <module 'time' (built-in)>}

          繼續(xù),因為 vars() 相當(dāng)于 locals(),所以代碼globals() == locals() == vars()成立,結(jié)果為 True 。

          最后調(diào)用 dir(),返回當(dāng)前局部作用域的符號表字典對應(yīng)的 keys()

          >>> dir() #去掉 __ 開頭的屬性
          ['pi''time']

          因為 dir() 返回的是局部變量字典的 keys,又因為這里局部變量和全局變量一致,加上 vars() 又相當(dāng)于 locals(),所以實際上,可以得到如下等式。

          >>> sorted(dir()) == sorted(globals().keys()) == sorted(locals().keys()) == sorted(vars().keys())
          True

          目前為止的分析中,locals 和 globals 都在全局作用域中,vars 和 dir 都沒有參數(shù),下面分析特殊情況。

          特殊情況

          先來分析當(dāng) locals 和 globals 位于函數(shù)內(nèi)部時的情況。

          locals 和 globals 位于函數(shù)內(nèi)部

          看如下代碼

          zs = 'zhangsan'

          def hello(name):
              print(globals())
              print(locals())
              print(vars())
              print(dir())
              print('Hello,%s!'%name ) 

          ls = 'lisi'

          hello(ls) 

          在函數(shù)內(nèi)部,global() 返回的是全局作用域變量,所以 zs,ls 和 hello 函數(shù)都有。而 locals() 返回局部變量和自由變量,這里沒有閉包,只有函數(shù)形參 name。vars() 和 dir() 和上例相同,結(jié)果如下:

          {'ls''lisi''zs''zhangsan''hello': <function hello at 0x00667DB0>} 
          {'name''lisi'}
          {'name''lisi'}
          ['name']
          Hello,lisi!

          另外,確切地說,globals() 返回的是函數(shù)定義時的全局變量空間。所以,如果 zs 變量和 hello 函數(shù)定義在另一個文檔 lib.py 中,在本程序中 from lib import hello 后,再執(zhí)行,返回的是定義時的全局變量:{'zs': 'zhangsan', 'hello': <function hello at 0x00667DB0>}不會包含調(diào)用空間的全局變量 ls。

          下面說明當(dāng) vars 和 dir 有參數(shù)時的情況。

          vars 和 dir 帶參數(shù)執(zhí)行

          vars 和 dir 函數(shù)有參數(shù)時的功能如下:

          • vars(obj) 返回 obj 的 dict
          • dir(obj) 返回 obj 的屬性。

          vars(obj) 返回模塊、類、實例以及有 dict 屬性的對象的 dict 屬性。

          模塊、類以及實例中的 dict 指代模塊的命名空間或?qū)傩宰值洹?/p>

          如下代碼,新建一個類和類的實例,分別對類和實例進(jìn)行 vars 操作,可見:

          class Man:
              def __init__(self,age,name):
                  self.age = age
                  self.name = name

          zs = Man(21,'zhangsan')
          print(vars(Man))
          print(vars(zs))

          這其中,類返回的是編譯相關(guān)的對象,諸如弱引用、模塊名、文檔等。對象返回的是屬性,這里是對象屬性 age 和 name。

          {'__weakref__': <attribute '__weakref__' of 'Man' objects>, '__dict__': <attribute '__dict__' of 'Man' objects>, '__module__''__main__''__doc__': None, '__init__': <function Man.__init__ at 0x00657390>}
          {'age': 21, 'name''zhangsan'}

          dir(obj) 返回對象的有效屬性的名字,這個有效屬性根據(jù)模塊、類和對象等有所不同,大概是從 dict 中提取的,但又不全然這樣。

          雖然常在交互模式下 dir() 查詢對象,但這查詢并不完全。

          看實例和類的差別。

          print(set(dir(zs))-set(dir(Man)))

          以上代碼對 zs 實例和 Man 類的 dir() 執(zhí)行結(jié)果求差集,可知對象實例與類實例相比,多了 {'age', 'name'} 兩個屬性,這也是 zs 實例的應(yīng)有之義。

          分析了半天的 globals、locals、vars和 dir,它們有什么用呢?

          作用

          了解、分析對象用法

          我們常在 REPL 命令行中用 dir() 來查看類或?qū)ο笾С值姆椒ā碛械膶傩裕@在認(rèn)識新包、編寫程序需要提示時比較有作用。比如 import time 后,忘記 time 的方法了,可以 dir(time) 一下。

          globals 和 locals 可以幫助認(rèn)識函數(shù)的作用域,了解當(dāng)前作用域的變量,分析局部、全局、自由變量。

          另外,借助于 globals 和 Locals 可以實現(xiàn)動態(tài)編寫代碼。

          動態(tài)編寫代碼

          如下代碼,用 exec 動態(tài)執(zhí)行 Python 代碼,生成新的變量 s。這里 exec 第一個參數(shù)時源代碼,第二個參數(shù)是源代碼的全局變量環(huán)境,第三個參數(shù)是源代碼的局部變量環(huán)境。

          取當(dāng)前全局變量字典(為了用全局變量 math 中的 pi)做第二個參數(shù)。

          取當(dāng)前局部變量字典,并稍作修改,加入 r 局部變量,形成 loc 字典做第三個參數(shù)。

          import math 
          loc = locals()
          loc['r'] = 10
          print('exec',exec('s = math.pi * r * r'),globals(),loc)

          print(s)
          print(locals()['s'])

          可得計算結(jié)果 314.159。用 print(s) 輸出,說明這里的 s 是動態(tài)生成的。又用 locals()['s'] 輸出,說明這里的 s 賦值給了局部作用域字典。

          總結(jié)

          本文先說明 globals ()、locals()、vars()、dir() 這些函數(shù)最直接的功能,然后對特殊情況進(jìn)行解釋,最后說明這些函數(shù)在理解變量作用域、分析對象、動態(tài)編碼中的作用。

          作者:鞏慶奎,大奎,對計算機、電子信息工程感興趣。gongqingkui at 126.com


          --END--

          老表薦書

          圖書介紹實戰(zhàn)大數(shù)據(jù)(Hadoop+Spark+Flink)詳細(xì)介紹了大數(shù)據(jù)工程師在實際工作中應(yīng)該熟練掌握的大數(shù)據(jù)技術(shù)。全書共8章,分別是大數(shù)據(jù)技術(shù)概述、搭建IDEA開發(fā)環(huán)境及Linux虛擬機、基于Hadoop構(gòu)建大數(shù)據(jù)平臺、基于HBase和Kafka構(gòu)建海量數(shù)據(jù)存儲與交換系統(tǒng)、用戶行為離線分析—構(gòu)建日志采集和分析平臺、基于Spark的用戶行為實時分析、基于Flink的用戶行為實時分析、用戶行為數(shù)據(jù)可視化。

          掃碼即可加我微信

          老表朋友圈經(jīng)常有贈書/紅包福利活動


          學(xué)習(xí)更多:
          整理了我開始分享學(xué)習(xí)筆記到現(xiàn)在超過250篇優(yōu)質(zhì)文章,涵蓋數(shù)據(jù)分析、爬蟲、機器學(xué)習(xí)等方面,別再說不知道該從哪開始,實戰(zhàn)哪里找了

          優(yōu)秀的讀者都知道,“點贊”傳統(tǒng)美德不能丟 

          瀏覽 68
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久国产精品毛片 | 久操网大香蕉 | 男人天堂新地址 | 一级a做视频在线免费观看 | 五月天丁香激情 |