Python名稱空間和作用域,閉包函數

来源:https://www.cnblogs.com/zhangfanshixiaobai/archive/2023/09/07/17685546.html
-Advertisement-
Play Games

# Python名稱空間和作用域,閉包函數 - 名稱的查詢順序 - 名稱空間的作用域 - global和nonlocal關鍵字的使用 - 函數對象(函數名) - 函數的嵌套調用 - 函數的嵌套定義 - 閉包函數 ## 名稱空間 ### 定義 ```python # 什麼是名稱空間? 名稱空間即存放名 ...


Python名稱空間和作用域,閉包函數

  • 名稱的查詢順序
  • 名稱空間的作用域
  • global和nonlocal關鍵字的使用
  • 函數對象(函數名)
  • 函數的嵌套調用
  • 函數的嵌套定義
  • 閉包函數

名稱空間

定義

# 什麼是名稱空間?
	名稱空間即存放名字與對象映射/綁定關係的地方。
	就是存放變數名與變數值關係的地方

名稱空間的分類

1.內置的名稱空間
	內置:就在python解釋器裡面,可以直接使用
        """一般大多數都是在函數內部存在的都是局部的!"""
        def index():
            a=1
            b=2
2.全局的名稱空間
	全局:在py文件中頂格編寫的變數名就是全局變數
    		 name='jerry'
             def index():
                    pass
                
             if a:
                pass
            
             while b:
                    pass
                
             for i in range(10):
                pass
            
全局變數:
	在函數外的變數就是全局變數
局部變數:
	在函數內部的變數就是局部變數
    

名稱查詢順序

既然有全局變數和局部變數那麼就一定會有查詢順序

名稱空間的載入順序是(在內置):內置名稱空間->全局名稱空間->局部名稱空間
如果你在全局:全局--->內置
局部變數在外部是不能被使用的
在函數內部列印出來的結構都屬於當前函數的局部名稱空間
"""局部名稱空間的嵌套!"""

def f1():
    # x = 222
    def f2():
        print('f2')
        # x = 333
        def f3():
            print('f3')
            # x = 444
            def f4():
                # x = 555
                print(x)
            f4()
        f3()
    f2()
f1()

名稱空間的作用域

域:範圍

作用域:變數的作用範圍

1. 內置名稱空間
	# 在全局的任意位置都能夠使用
2. 全局名稱空間
	# 在全局的任意位置任意時間都能夠使用
 3. 局部名稱空間
	# 一般情況只能夠在局部使用
    
 def index():
    x = 666
   

global和nonlocal的使用

global

如果你想在局部修改全局的變數:
		1. 如果你修改的是不可變的類型,需要global關鍵字的聲明
		2. 如果你修改的是可變類型的,無需使用global關鍵字聲明
# x = 10

# def index():
#     global x # 聲明這個x用的是全局的x
#     x = 20  # 我想在局部修改全局的x的值
#     # print(x)
#
# index()
# print(x) # 10


name_list = ['kevin', 'jerry']


def func():
    name_list.append('tank')


func()
print(name_list) # ['kevin', 'jerry', 'tank']

nonlocal
如果你想在內部的局部修改外部的局部:
		1. 如果你修改的是不可變的類型,需要nonlocal關鍵字的聲明
		2. 如果你修改的是可變類型的,無需使用nonlocal關鍵字聲明
nonlocal的使用:
# def outer():
#     x = 666
#     def inner():
#         nonlocal x
#         x = 999
#     inner()
#     print(x) # 此時的x是多少? 666
#
# outer()

def outer():
    name_list = ['a', 'b']
    def inner():
        name_list.append('c')
    inner()
    print(name_list) # 此時的x是多少? 666

outer()

函數對象(函數名)

函數名可以當成變數賦值

ef index():
    print('index')
    return 123

# print(index())
'''函數名就是函數在記憶體中得地址'''
# print(index)  # <function index at 0x0000022FD03AD550>

a = index
# print(a) # <function index at 0x0000022D4E03D550>
res=a()  # index()
print(res)

函數名可以的當成函數的實參

def index():
    print('index')
    return None

def func(a):
    # a:index
    print(a)
    res=a()  # index()
    print(res) # res的結果? None

# index:index函數所在的記憶體地址

函數名可以當成函數的返回值

def index():
    print('index')
    return 'index2'

def func():
    print('func')
    # return index() # 'index'
    return index # 'index'

res = func()  #
print(res)
res1=res()  # index()
print(res1)

函數名可以當成容器類型的元素

def index(): 
   print('index')   
return Nonell = [11, 22, 33, index]
# ll = [11, 22, 33, index()]# print(ll[3])
res=ll[3]() # index()
print(res)

函數的嵌套調用

嵌套:函數套函數
# 案例:給你四個數,比較大小,返回最大的
# 兩個數的比較大小,返回大的

def my_max(a, b):
    if a >b:
        return a
    return b

# res=my_max(1, 2)
# print(res)

##
def many_max(a, b, c, d, e):
    '''四個數的比較大小其實還是要兩兩比較!'''
    res=my_max(a, b) # res得到a和b中得大的那個
    # 怎麼樣比較res和剩餘的大小, 只需要拿res和c或者d中得一個進行比較
    res1=my_max(res, c) # res1:a,b,c中得最大的那個
    res2=my_max(res1, d)
    res3=my_max(res2, e)
    return res3

res=many_max(11, 12, 3, 24)
print(res)

閉包函數

# 閉包函數還是函數,它是有函數一點一點演變過來的

什麼是閉包函數?
	閉:就是函數內部定義函數,至少要有2層函數
    包:內部的函數要使用外部函數名稱空間中的名字
    
'''只有同時滿足以上兩個條件,才能稱之為是閉包函數'''

def outer():
    x = 666
    def inner():
        print('hello', x)
    return inner

outer()


# 閉包函數的使用場景:
閉包函數其實是第二種傳參方式!

# 第一種傳參方式

# def index(username):
#     print(username)
#
# index('jerry')

# 第二種傳參方式
# 比較兩個數的大小
# def my_max(a, b):
#     if a>b:
#         return a
#     return b
#
# my_max(1, 2)


# 讓你用閉包函數實現比較2個數的大小:一次傳值,多次使用
def outer(a, b):
    # a = 100
    # b = 200

    def my_max():
        if a > b:
            return a
        return b

    return my_max


res = outer(1, 10)  # my_max函數的記憶體地址
print(res()) # my_max()
print(res()) # my_max()
print(res()) # my_max()
print(res()) # my_max()
print(res()) # my_max()
print(res()) # my_max()
print(res()) # my_max()
print(res()) # my_max()

res1=outer(10, 20) # res1:my_max
print(res1())
print(res1())
print(res1())
print(res1())
print(res1())
print(res1())
print(res1())
print(res1())
print(res1())

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ### 歡迎訪問我的GitHub > 這裡分類和彙總了欣宸的全部原創(含配套源碼):[https://github.com/zq2599/blog_demos](https://github.com/zq2599/blog_demos) ### 關於《LeetCode買賣股票》系列 - 在LeetC ...
  • 隨著金融科技的發展,越來越多的人選擇線上銀行或移動銀行上進行日常交易。在進行這些交易之前,通常需要進行身份驗證以確保賬戶的安全性。其中,銀行卡二要素驗證是一種常見的身份驗證方式。本文將為大家介紹如何使用銀行卡二要素驗證API介面,具體實現方法如下。 一、API介面介紹 銀行卡二要素驗證API介面是一 ...
  • JDK 代理和 CGLib 有什麼區別? 動態代理是一種機制,程式通過該機制在運行時動態生成代理對象並調用代理方法。動態代理主要有兩種實現機制,一種是基於反射動態代理的JDK,另一種是基於ASM動態代理機制的CGLib實現。現在讓我們談談兩種實現之間的區別以及如何實現它們 JDK 代理和 CGLib ...
  • ### 前言 上篇文章[10分鐘從源碼級別搞懂AQS(AbstractQueuedSynchronizer)](https://juejin.cn/post/7273506068104478760)說到JUC併發包中的同步組件大多使用AQS來實現 本篇文章通過AQS自己來實現一個同步組件,並從源碼級 ...
  • 函數是一組語句,可以在程式中重覆使用。函數不會在頁面載入時自動執行。函數將通過調用函數來執行。 ### 創建函數 要創建(通常稱為聲明)一個函數,請執行以下操作: - 使用 `func` 關鍵字。 - 指定函數的名稱,後跟括弧 `()`。 - 最後,在花括弧 `{}` 內添加定義函數應執行的代碼。 ...
  • 1.雙擊圖標 2.彈出如下對話框: 3、單擊按鈕Next,彈出如下對話框: 4、單擊按鈕I Agree,彈出如下對話框: 5、單擊按鈕Next,彈出如下對話框: 6、單擊Browse按鈕,可以重新設置安裝路徑 7、路徑重新設置後,單擊確定按鈕彈出如下對話框(註意,此時路徑已更改): 註意:如果想要設 ...
  • # 集合總結 ## 一、概述 1. 作用:存儲對象的容器,代替數組的,使用更加的便捷 2. 所處的位置:java.util 3. 體繫結構 ![image](https://img2023.cnblogs.com/blog/3245131/202309/3245131-202309071934421 ...
  • Vue 3 的Composition API + ``` ``` 這就把清單功能獨立出來,可在任意需要的地方復用。 基於組件去搭建應用,可實現對業務邏輯的復用。如有其他頁面也需要用到這功能,直接復用。 然後,就可基於新語法實現清單應用。 把之前的代碼移植過來後,使用ref包裹的響應式數據。修改tit ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...