欧美一区二区三区,国内熟女精品熟女A片视频小说,日本av网,小鲜肉男男GAY做受XXX网站

python的爬蟲都有什么內置函數

李中冰2年前12瀏覽0評論

python的爬蟲都有什么內置函數?

函數

一.引言

a) 概念:函數是完成指定或者特定任務的一組代碼。在面向對象編程的類中函數通常被稱為方法。不同的函數在程序中會扮演不同的角色完成不同的功能。

b) 作用:

i. 函數的使用可以提高代碼的復用性,省去重復代碼的編寫,提升程序代碼重復利用率。

ii. 函數能封裝內部的實現,保護內部的數據。通常,我們可以將函數看做成一個“黑盒子”。往往函數的使用者并不是函數的編寫者,函數的使用者并不需要對函數內部實現和行為進行考慮,可以將精力更多投入到自身業務邏輯的設計中。只有函數的編寫者才需要考慮函數內部的實現細節,如何暴露對外的接口,返回什么樣的數據值,也就是API的設計。

iii. 提高程序的可讀性。使得程序模塊化。從一盤散散沙變成整齊隊列。

iv. 提高程序的可維護性。案例:打印一個不同字符組成的分隔符。

二.函數基礎

a) 可以將函數抽象成現實生活中的工具。工具需要先制作出來才可以使用。函數也是一樣的需要先進行函數的定義,然后方可進行函數調用。

b) 函數定義語法結構:

def 函數名(參數):

# 內部代碼

return 表達式

c) Return:return不是必須要寫的,如果需要則寫,不需要可不寫。Return后面什么都不跟表示return None。一旦函數執行過程中遇到了return語句,那么函數中return后面的所有語句將不會執行,函數執行結束。

d) 函數調用:

i. 語法結構:函數名(參數值)

ii. 注意事項:

1. 參數之前使用逗號隔開

2. 由于python動態語言的特點,函數調用時填寫的參數,python不會對參數類型進行檢查,如果函數調用中的參數不符合函數內部運行機制的話,會報錯。

e) 參數:現實函數和調用者之間的交互

i. 函數-》工具:使用ATM取錢時需要傳入密碼數據。

ii. 實參和形參的概念。

iii. 函數調用時,實參會傳值給形參

1. 注意:

a) Python的函數參數傳遞實際上傳遞的是實參的地址

b) Python中的參數類型分為可變數據類型和不可變數據類型。

2. Test:使用可變數據類型和不可變數據類型的數據作為參數

a = 1

def func(a):

print("在函數內部修改之前,變量a的內存地址為: %s" % id(a))

a = 2

print("在函數內部修改之后,變量a的內存地址為: %s" % id(a))

print("函數內部的a為: %s" % a)

print("調用函數之前,變量a的內存地址為: %s" % id(a))

func(a)

print("函數外部的a為:%s" % a)

打印結果為:

調用函數之前,變量a的內存地址為: 1401140288

在函數內部修改之前,變量a的內存地址為: 1401140288

在函數內部修改之后,變量a的內存地址為: 1401140320

函數內部的a為: 2

函數外部的a為:1

解釋:作為參數,a被傳入函數時,將數字對象1的地址傳遞給了函數內部的a。執行第一句內部代碼時,此時內部的a和外面的a其實是一個東西,因此打印出了同樣的內存地址。而當a=2被執行后,由于整數是不可變的數據類型,所以創建了一個新的內部變量a,并賦值2,將數字對象2的內存地址賦給變量a。我們知道,首先,賦值語句具有創建新變量的功能。

剛才說的是不可變類型參數,如果是可變類型的,比如列表呢?

a = [1, 2, 3]

def func(b):

print("在函數內部修改之前,變量b的內存地址為: %s" % id(b))

b.append(4)

print("在函數內部修改之后,變量b的內存地址為: %s" % id(b))

print("函數內部的b為: %s" % b)

print("調用函數之前,變量a的內存地址為: %s" % id(a))

func(a)

print("函數外部的a為:%s" % a)

執行結果是:

調用函數之前,變量a的內存地址為: 34875720

在函數內部修改之前,變量b的內存地址為: 34875720

在函數內部修改之后,變量b的內存地址為: 34875720

函數內部的b為: [1, 2, 3, 4]

函數外部的a為:[1, 2, 3, 4]

三.參數類型:python函數的參數定義靈活度很大,可以定義位置參數,默認參數,動態參數,關鍵字參數等。

a) 位置參數

i. 概念:也叫做必傳參數,在函數調用時必須明確提供的參數,切參數順序個數必須和形參保持一致。但是如果在函數調用的時候給實參指定參數名,那么位置參數的順序可以不同。

b) 默認參數:如果給某個參數提供一個默認值,該參數就是默認參數。在函數調用時,可以給默認參數傳遞一個值,也可以使用默認值。

i. Test:

def power(x, n = 2):

return x**n

ret1 = power(10) # 使用默認的參數值n=2

ret2 = power(10, 4) # 將4傳給n,實際計算10**4的值

ii. 使用默認參數的注意事項:

1. 默認參數必須在順序參數后面

2. 默認參數盡量指向不變的對象

a) Test:

下面是國內某上市互聯網公司Python面試真題:

def func(a=[]):

a.append("A")

return a

print(func())

print(func())

print(func())

不要上機測試,僅憑代碼,你能說出打印的結果嗎?

很多同學可能會說,這還不簡單,肯定是下面的結果啊:

['A']

['A']

['A']

真的是這樣嗎?錯了!真正的結果是:

['A']

['A', 'A']

['A', 'A', 'A']

Why?為什么會這樣?

因為Python函數體在被讀入內存的時候,默認參數a指向的空列表對象就會被創建,并放在內存里了。因為默認參數a本身也是一個變量,保存了指向對象[]的地址。每次調用該函數,往a指向的列表里添加一個A。a沒有變,始終保存的是指向列表的地址,變的是列表內的數據!我們可以測試一下:

def func(a=[]):

print("函數內部a的地址為:%s" % id(a))

a.append("A")

return a

b = func()

print('此時b的值為:%s' % b)

print("函數外部b的地址為:%s" % id(b))

print("-------------")

c = func()

print('此時c的值為:%s' % c)

print("函數外部c的地址為:%s" % id(c))

print("-------------")

d = func()

print('此時d的值為:%s' % d)

print("函數外部d的地址為:%s" % id(d))

打印結果是:

函數內部a的地址為:39287880

此時b的值為:['A']

函數外部b的地址為:39287880

-------------

函數內部a的地址為:39287880

此時c的值為:['A', 'A']

函數外部c的地址為:39287880

-------------

函數內部a的地址為:39287880

此時d的值為:['A', 'A', 'A']

函數外部d的地址為:39287880

那么如何避免這個問題呢?

使用不可變的數據類型作為默認值!

def func(a=None):

# 注意下面的if語句

if a is None:

a = []

a.append("A")

return a

print(func())

print(func())

print(func())

將默認參數a設置為一個類似None,數字或字符串之類的不可變對象。在函數內部,將它轉換為可變的類型,比如空列表。這樣一來,不管調用多少次,運行結果都是['A']了。

iii. 動態參數

1. 概念:函數調用時傳入的參數可以是動態數量的,可以為任意個,甚至是0個。

2. 分類:重點是*的個數,*后的名字任意。動態參數必須放在所有位置參數和動態參數后面。

a) *args:可以接受任意個參數。調用時,會將實參打包成一個元組傳給形參。如果參數是一個列表,則會將整個列表當做一個參數傳入。

i. Test

def func(*args):

for arg in args:

print(arg)

func('a', 'b', 'c')

li = [1, 2, 3]

func(li)

ii. 上述案例中,我們本意是將li這個列表中的元素作為參數進行傳值,但是實際卻是將列表本身作為一個整體進行了傳遞。如果想要將一個序列類型的對象(元組,列表,字符串,字典)的元素依次作為參數進行傳遞,則可以在序列對象前加一個*即可。如果參數是字典,則會將字典所有的key逐一傳遞進去。

1. Test:

def func(*args):

for arg in args:

print(arg)

li = [1, 2, 3]

func(*li)

b) **kwargs:表示接受鍵值對的動態參數,數量任意。調用時,會將參數打包成一個字典。

i. Test:

def func(**kwargs):

for kwg in kwargs:

print(kwg, kwargs[kwg])

print(type(kwg))

func(k1='v1', k2=[0, 1, 2])

運行結果是:

k1 v1

k2 [0, 1, 2]

ii. 而如果我們這樣傳遞一個字典dic呢?我們希望字典內的鍵值對能夠像上面一樣被逐一傳入。

1. Test:

def func(**kwargs):

for kwg in kwargs:

print(kwg, kwargs[kwg])

dic = {

'k1': 'v1',

'k2': 'v2'

}

func(**dic)

iv. 關鍵字參數:關鍵字參數前面需要一個特殊分隔符*和位置參數及默認參數分隔開來。*后面的參數被視為關鍵字參數。在函數調用時,關鍵字參數必須傳入參數名。

1. Test:

def student(name, age, *, sex):

pass

student(name="jack", age=18, sex='male')

Test2:如果函數定義中已經有了一個*args參數,后面跟著的命名關鍵字參數就不再需要一個特殊分隔符*了。

def student(name, age=10, *args, sex, classroom, **kwargs):

pass

student(name="jack", age=18, sex='male', classroom="202", k1="v1")

總結:參數定義順序:位置參數,動態參數,關鍵字參數,動態參數