Python基礎(chǔ)教程(第三版)(六) 抽象

一個菜雞的掙扎
就總結(jié)下
and 如果有大佬不小心看到了發(fā)現(xiàn)了錯誤,就歡迎指正

6.1懶惰是一種美德

通過創(chuàng)建函數(shù)調(diào)用之可以減少代碼量

6.2 抽象和結(jié)構(gòu)

抽象是程序能夠被人理解的關(guān)鍵所在(無論對編寫程序還是閱讀來說,這都至關(guān)重要)

函數(shù)封裝了人不需要關(guān)心的實現(xiàn)細(xì)節(jié),從而更容易被使用和理解

6.3 自定義函數(shù)

6.3.1 給函數(shù)編寫文檔

在def后面添加字符串,相當(dāng)于給整個函數(shù)添加注釋,以確保被人理解
_doc _是函數(shù)的一個屬性,可用它來訪問函數(shù)的文檔字符串
我自己的練習(xí):

def lalala(x):
    """就瞎寫的"""
    print(x)

print(lalala.__doc__)

結(jié)果:


運行結(jié)果

這里書上說用單引號,但是pycharm中會有提示,要讓用連續(xù)的三個雙引號
help()函數(shù)可訪問有關(guān)函數(shù)的信息,其中會包含函數(shù)的文檔字符串

In [1]: help(round)
Help on built-in function round in module builtins:

round(...)
    round(number[, ndigits]) -> number

    Round a number to a given precision in decimal digits (default 0 digits).
    This returns an int when called with one argument, otherwise the
    same type as the number. ndigits may be negative.

6.3.2 其實并不是函數(shù)的函數(shù)

就是有的函數(shù)沒有return 或者return后面沒有指定值,這么做將會返回None

6.4 參數(shù)魔法

6.4.1 值從哪里來 略

6.4.2 我能修改參數(shù)嗎

可變參數(shù)可以,不可變參數(shù)不可以
如果不想讓可變參數(shù)的值在調(diào)用函數(shù)后發(fā)生變化,可以向函數(shù)中傳遞切片或者用copy()傳遞副本(如果有copy()的話)
自己的練習(xí):

def change(n):
    n[0] = 'a'


x = [1, 2, 3]
change(x)
print(x)

結(jié)果;


change(x[:])
print(x)

結(jié)果:


change(x.copy())
print(x)

結(jié)果:



如果想讓不可變參數(shù)發(fā)生變化,可以使之重新指向返回的值,或者干脆把它放在列表中

6.4.3 關(guān)鍵字參數(shù)和默認(rèn)值

這個部分之前看過了,少總結(jié)下

像這種用名稱指定的參數(shù)稱為關(guān)鍵字參數(shù),主要優(yōu)點是有助于澄清各個參數(shù)的作用。

關(guān)鍵字參數(shù)在傳入時的順序與定義時的不一樣也沒關(guān)系,反正有關(guān)鍵字程序不會認(rèn)錯
可以為關(guān)鍵字參數(shù)設(shè)置默認(rèn)值,如果在調(diào)用該參數(shù)沒有傳入,就使用默認(rèn)值
位置參數(shù)不可定義在關(guān)鍵字參數(shù)后面!
關(guān)鍵字好像只能是字符串,我的試驗:

def test(*a, **b):
    print(a, b)

b = {1: 'a', 2:'b'}
test(1, **b)

然后會報錯:


6.4.4 收集參數(shù)

帶星號的參數(shù)會收集多余的值,放在元組中
一個星號不會收集關(guān)鍵字參數(shù)!若想收集,可帶兩個星號,這樣會得到字典而非數(shù)組
位置參數(shù)最好不要放在星號參數(shù)后面,雖然指定名稱也可以調(diào)用

6.4.5 分配參數(shù)

類似于序列解包,可大致理解為與收集參數(shù)相反的操作

6.5 作用域

  • vars()函數(shù) ,返回作用域中看不見的字典,最好不要使用它修改字典中的值,因為其結(jié)果是不確定的
  • 在函數(shù)中讀取全局變量而非訪問它,一般不會造成任何問題,但這樣通常會不小心寫出Bug
  • 如果局部變量與全局變量重名,必要時可使用globals()['變量名']來訪問它,globals()類似于vars(),也返回一個字典
  • 在函數(shù)中定義變量時,可在前面加入global 來聲明它是全局變量
  • 作用域嵌套,可在函數(shù)中再定義函數(shù),并用return返回這個函數(shù)

在函數(shù)中訪問全局變量:

# 在函數(shù)中訪問全局變量
y = '全局'
def test(x):
    print(x+y)
test('局部')

結(jié)果:

在函數(shù)中訪問全局變量

PS:做作業(yè)時發(fā)現(xiàn)np.array不用gobal關(guān)聯(lián)也會變化,于是猜測,可變變量似乎不用關(guān)聯(lián)也會變化

如果局部變量與全局變量重名:

# 如果局部變量與全局變量重名
y = '全局'
def test(y):
    print(y+globals()['y'])
test('局部')

結(jié)果同上
重新關(guān)聯(lián)全局變量:

# 重新關(guān)聯(lián)全局變量
y = '全局'
def test():
    global y
    y = '我變了'
test()
print(y)

結(jié)果:

重新關(guān)聯(lián)全局變量

關(guān)于作用域嵌套:

In [2]: def first(x):
   ...:     def second(y):
   ...:         return y**x
   ...:     return second
   ...: fun = first(2)
   ...: fun(2)
Out[2]: 4

6.6 遞歸

這個就不說了

函數(shù)式編程

  • 主要說了map,filter,reduce,lambda
  • 在較新的python版本中,可以用列表推導(dǎo)代替map和filter
  • map:對列表中所有元素執(zhí)行函數(shù)
In [3]: list(map(str,range(10)))
Out[3]: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

In [4]: # 與下面等價

In [5]: [str(i) for i in range(10)]
Out[5]: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
  • filter: 對序列中元素執(zhí)行函數(shù),若為結(jié)果真,把它添加到最終要返回的列表中
In [6]: def  fun(x):
   ...:     return x.isalnum()
   ...: list(filter(fun,['fdas','fdsa3','1*&']))
Out[6]: ['fdas', 'fdsa3']
# 與[x for x in [....] if x.isalnum] 等價
  • reduce: 這個還是看例子
In [1]: from functools import reduce
In [2]: reduce(lambda x,y: x+y, [1,2,3,4,5,6,7,8,9])
Out[2]: 45 

lambda的作用很明顯了

補充:

通常,不能給外部作用域內(nèi)的變量賦值,但如果一定要這樣做,可使用關(guān)鍵字nonlocal。這個關(guān)鍵字的用法與global很像,讓你能夠給外部作用域(非全局作用域)內(nèi)的變量賦值。

總結(jié)

抽象、函數(shù)定義、函數(shù)傳參、作用域、函數(shù)式編程(主要是函數(shù)式編程工具,用以代替定義函數(shù))
完了,希望不是在做無用功

Python基礎(chǔ)教程(第三版)(七)再談抽象

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容