網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
一、定義函數(shù)
在Python中可以使用def關(guān)鍵字來(lái)定義函數(shù),命名規(guī)則跟變量的命名規(guī)則是一致的。在函數(shù)名后面的圓括號(hào)中可以放置傳遞給函數(shù)的參數(shù),而函數(shù)執(zhí)行完成后我們可以通過(guò)return關(guān)鍵字來(lái)返回一個(gè)值。
定義代碼如下:
def fac(num): ? ? """求階乘""" ? ? result = 1 ? ? for n in range(1, num + 1): ? ? ? ? result *= n ? ? #返回值 ? ? return result
二、函數(shù)的參數(shù)
在Python中,函數(shù)的參數(shù)可以有默認(rèn)值,也支持使用可變參數(shù),所以Python并不需要像其他語(yǔ)言一樣支持函數(shù)的重載,因?yàn)槲覀冊(cè)诙x一個(gè)函數(shù)的時(shí)候可以讓它有多種不同的使用方式,
下面是兩個(gè)小例子:
from random import randint ? ? def roll_dice(n=2): ? ? """搖色子""" ? ? total = 0 ? ? for _ in range(n): ? ? ? ? total += randint(1, 6) ? ? return total ? ? def add(a=0, b=0, c=0): ? ? """三個(gè)數(shù)相加""" ? ? return a + 2 * b + 3 * c ? ? # 如果沒(méi)有指定參數(shù)那么使用默認(rèn)值搖兩顆色子 print(roll_dice()) # 搖三顆色子 print(roll_dice(3)) #函數(shù)重載,沒(méi)有指定函數(shù)變量時(shí),參數(shù)按照順序傳值 print(add()) print(add(1)) print(add(1, 2)) print(add(1, 2, 3)) # 傳遞參數(shù)時(shí)可以不按照設(shè)定的順序進(jìn)行傳遞 print(add(c=50, a=100, b=200)) # 或者可以不傳 print(add(c=50, b=200)) ? if __name__ == '__main__': ? ? pass
沒(méi)有傳入對(duì)應(yīng)參數(shù)的值時(shí)將使用該參數(shù)的默認(rèn)值。
不確定參數(shù)個(gè)數(shù)的時(shí)候,我們可以使用可變參數(shù),代碼如下所示:
# 在參數(shù)名前面的*表示args是一個(gè)可變參數(shù) def add(*args): ? ? total = 0 ? ? for val in args: ? ? ? ? total += val ? ? return total ? ? # 在調(diào)用add函數(shù)時(shí)可以傳入0個(gè)或多個(gè)參數(shù) print(add()) print(add(1)) print(add(1, 2)) print(add(1, 2, 3)) print(add(1, 3, 5, 7, 9))
三、用模塊管理函數(shù)
由于Python沒(méi)有函數(shù)重載的概念,那么后面的定義函數(shù)會(huì)覆蓋之前的定義,也就意味著兩個(gè)函數(shù)同名函數(shù)實(shí)際上只有一個(gè)是存在的。
def foo(): ? ? print('hello, world!') ? ? def foo(): ? ? print('goodbye, world!') ? ? # 下面的代碼會(huì)輸出什么呢? foo() ? if __name__ == '__main__': ? ? pass ? #實(shí)際輸出 goodbye, world!
多人協(xié)作進(jìn)行團(tuán)隊(duì)開(kāi)發(fā)的時(shí)候,團(tuán)隊(duì)中可能有多個(gè)程序員都定義了名為foo的函數(shù),那么怎么解決這種命名沖突呢?
重點(diǎn)如何避免函數(shù)覆蓋!!!
在Python中每個(gè).py文件就代表了一個(gè)模塊(module),我們?cè)诓煌哪K中可以有同名的函數(shù),在使用函數(shù)的時(shí)候我們通過(guò)import
關(guān)鍵字導(dǎo)入指定的模塊就可以區(qū)分到底要使用的是哪個(gè)模塊中的foo
函數(shù),
代碼如下所示:
module1.py ? def foo(): ? ? print('hello, world!') ? module2.py ? def foo(): ? ? print('goodbye, world!')
導(dǎo)入模塊:
test.py ? import module1 as m1 import module2 as m2 ? m1.foo() m2.foo()
注意:但是如果將代碼寫(xiě)成了下面的樣子,那么程序中調(diào)用的是最后導(dǎo)入的那個(gè)foo,因?yàn)楹髮?dǎo)入的foo覆蓋了之前導(dǎo)入的foo。
from module1 import foo from module2 import foo ? # 輸出goodbye, world!,使用的是后導(dǎo)入的模塊 foo()
需要說(shuō)明的是,如果我們導(dǎo)入的模塊除了定義函數(shù)之外還有可以執(zhí)行代碼,那么Python解釋器在導(dǎo)入這個(gè)模塊時(shí)就會(huì)執(zhí)行這些代碼,事實(shí)上我們不想執(zhí)行這些代碼,那我們將可執(zhí)行代碼放入如下所示的條件中,這樣的話除非直接運(yùn)行該模塊,if條件下的這些代碼是不會(huì)執(zhí)行的,因?yàn)橹挥兄苯訄?zhí)行的模塊的名字才是"__main__"
。
def foo(): ? ? pass ? def bar(): ? ? pass ? # __name__是Python中一個(gè)隱含的變量它代表了模塊的名字 # 只有被Python解釋器直接執(zhí)行的模塊的名字才是__main__ if __name__ == '__main__': ? ? print('call foo()') ? ? foo() ? ? print('call bar()') ? ? bar()
import module3 # 導(dǎo)入module3時(shí) 不會(huì)執(zhí)行模塊中if條件成立時(shí)的代碼 因?yàn)槟K的名字是module3而不是__main__
四、變量的作用域?
def foo(): ? ? b = 'hello' ? ? ? # Python中可以在函數(shù)內(nèi)部再定義函數(shù) ? ? def bar(): ? ? ? ? c = True ? ? ? ? print(a) ? ? ? ? print(b) ? ? ? ? print(c) ? ? ? bar() ? ? # print(c) ?# NameError: name 'c' is not defined ? ? if __name__ == '__main__': ? ? a = 100 ? ? # print(b) ?# NameError: name 'b' is not defined ? ? foo()
打印結(jié)果:
100
hello
True
上面的代碼能夠順利的執(zhí)行并且打印出100、hello和True,但我們注意到了,在bar函數(shù)的內(nèi)部并沒(méi)有定義a和b兩個(gè)變量,那么a和b是從哪里來(lái)的。
我們?cè)谏厦娲a的if分支中定義了一個(gè)變量a,這是一個(gè)全局變量(global variable),屬于全局作用域,因?yàn)樗鼪](méi)有定義在任何一個(gè)函數(shù)中。
在上面的foo函數(shù)中我們定義了變量b,這是一個(gè)定義在函數(shù)中的局部變量(local variable),屬于局部作用域,在foo函數(shù)的外部并不能訪問(wèn)到它;但對(duì)于foo函數(shù)內(nèi)部的bar函數(shù)來(lái)說(shuō),變量b屬于嵌套作用域,在bar函數(shù)中我們是可以訪問(wèn)到它的。
bar函數(shù)中的變量c屬于局部作用域,在bar函數(shù)之外是無(wú)法訪問(wèn)的。
Python查找變量順序:
“局部作用域”-》“嵌套作用域”-》“全局作用域”和“內(nèi)置作用域”的順序進(jìn)行搜索。
內(nèi)置作用域:Python內(nèi)置的那些標(biāo)識(shí)符,我們之前用過(guò)的input、print、int等都屬于內(nèi)置作用域。
我們希望通過(guò)函數(shù)調(diào)用修改全局變量a的值,但實(shí)際上下面的代碼是做不到的。
代碼如下:
def foo(): ? ? a = 200 ? ? print(a) ?# 200 ? ? if __name__ == '__main__': ? ? #這里變量值不能修改函數(shù)局部變量的值 ? ? a = 100 ? ? foo() ? ? print(a) ?# 100
在調(diào)用foo函數(shù)后,我們發(fā)現(xiàn)a的值仍然是100,這是因?yàn)楫?dāng)我們?cè)诤瘮?shù)foo中寫(xiě)a = 200的時(shí)候,是重新定義了一個(gè)名字為a的局部變量,它跟全局作用域的a并不是同一個(gè)變量。
因?yàn)榫植孔饔糜蛑杏辛俗约旱淖兞縜,因此foo函數(shù)不再搜索全局作用域中的a。如果我們希望在foo函數(shù)中修改全局作用域中的a,
代碼如下所示:
def foo(): ? ? global a ? ? a = 200 ? ? print(a) ?# 200 ? ? if __name__ == '__main__': ? ? a = 100 ? ? foo() ? ? print(a) ?# 200
可以使用global關(guān)鍵字來(lái)指示foo函數(shù)中的變量a來(lái)自于全局作用域。
注:
在實(shí)際開(kāi)發(fā)中,我們應(yīng)該盡量減少對(duì)全局變量的使用,因?yàn)槿肿兞康淖饔糜蚝陀绊戇^(guò)于廣泛,可能會(huì)發(fā)生意料之外的修改和使用。
除此之外全局變量比局部變量擁有更長(zhǎng)的生命周期,可能導(dǎo)致對(duì)象占用的內(nèi)存長(zhǎng)時(shí)間無(wú)法被垃圾回收
原文鏈接:https://blog.csdn.net/xp_lx1/article/details/124386797
相關(guān)推薦
- 2022-05-24 Flutter滾動(dòng)組件之ListView使用方法詳解_Android
- 2022-06-10 C語(yǔ)言?模擬實(shí)現(xiàn)strcpy與strcat函數(shù)詳解_C 語(yǔ)言
- 2022-07-07 基于Python制作一個(gè)文件解壓縮工具_(dá)python
- 2022-04-11 C++實(shí)現(xiàn)簡(jiǎn)單的計(jì)算器小功能_C 語(yǔ)言
- 2022-10-11 MybatisPlus的UpdateWrapper和QueryWrapper的區(qū)別
- 2023-05-20 Golang中map的三種聲明定義方式實(shí)現(xiàn)_Golang
- 2022-04-04 Python?Opencv實(shí)現(xiàn)圖片切割處理_python
- 2022-07-29 Linux進(jìn)程管理方法介紹_linux shell
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支