1. 程式人生 > 實用技巧 >MongoDB 索引 和 explain 的使用

MongoDB 索引 和 explain 的使用

呼叫函式

函式名加括號即呼叫函式
定義階段:在定義階段只檢測語法,不執行函式體程式碼
呼叫階段:根據函式名找到函式的記憶體地址,然後執行函式體程式碼

定義階段:
def foo():
    print('from foo')  
    soo() #函式只要在發生呼叫之前被定義就行了,變數必須要經過定義才能被引用。也就是說函式在定義階段時可以寫其他還沒被定義的函式
def soo(): print('from soo') 呼叫階段: foo() 執行結果: from foo from soo

結論:定義階段函式foo與soo均無語法錯誤,而在呼叫階段呼叫foo()時,函式foo與soo都早已經存在於記憶體中了,所以不會有任何問題

函式的返回值

函式體程式碼執行完畢後需要有一個返回結果給呼叫者。

1、沒有return:預設返回None

2、只寫return:只有結束函式體程式碼的效果,返回None

3、寫return None: 與只寫return的效果一樣

4、return後跟一個值,返回該值本身

5、return可以用逗號隔開,返回多個值,返回的多個值存入一個元組返回


注意:
    1.return返回值的值,沒有型別限制,可以自己指定返回的資料型別
    2.返回的值不能被修改
    3.函式內可以寫多個return,return執行一次,函式就立刻結束,並把return後的值作為本次呼叫的

函式引數詳解一、 形參與實參

形參:即在定義函式時,括號內宣告的引數。形參本質就是一個變數名,用來接收外部傳來的值。
實參:即在呼叫函式時,括號內傳入的值,值可以是常量、變數、表示式或三者的組合。

注意:在呼叫函式時,實參值(變數的值)會賦值給形參(變數名),兩者的繫結關係只在函式呼叫時才會生效,在呼叫函式結束後就立刻接觸繫結

1.1、引數的形式

1、位置引數:通過位置從左到右的順序依次定義的引數

def foo(a,b)
    print(a,b)
foo(1,2)

注意:
1、位置形參的特性是在呼叫函式時必須為其傳值,而且多一個少一個都不行
2、位置實參與形參一一對應

2、關鍵字引數:在呼叫函式時,按照key=value的形式定義的實參

,稱為關鍵字引數

def foo(x,y,z):
    print(x,y,z)1
foo(x=1,y=2,z=3)
注意:
1、相當於指名道姓地為形參傳值,意味著即便是不按照順序定義,仍然能為指定引數傳值
2、在呼叫函式時,位置實參與關鍵字實參可以混合使用,但關鍵字實參必須要放在位置實參後,不能為同一個形參重複傳值

3、預設引數:在定義階段,已經為某個形參賦值,那麼該引數稱為預設引數

注意:
1、定義階段已經有值,意味著呼叫階段可以不傳值,但如果在實參的時候傳入新引數,就會使用新引數
def register(name,age,sex='male'):
    print(name,age,sex)
register('egon',18,'male')
register('alex',73,'female')
register('wxx',84,'male')

2、預設引數的值只在定義階段賦值一次,也就是說預設引數的值在定義階段就固定死了            #易錯點
m = 10
def foo(x,y=m)
    print(x,y)
m=111111
foo(1)
>>>1,10
>

3、預設引數在傳值的時候,不要將可變型別當作引數傳值
def register(name,hobby,l=[]):
    l.append(hobby)
    print(name,l)
register('egon','play')
register('alex','AK')
register('wxx','gun')


def register(name,hobby,l=[]):
    l.append(hobby)
    print(name,l)
register('egon','play',[])    #egon ['play']
register('alex','AK',[])    #alex ['AK']
register('wxx','gun',[])    #wxx ['gun']


def register(name,hobby,l=None):
    if l == None:
        l=[]
        l.append(hobby)
        print(name,l)
register('egon','play')  #egon ['play']
register('alex','AK')    #alex ['AK']
register('wxx','gun')    #wxx ['gun']

應用:對於經常需要變化的值,需要將對應的形參定義為位置形參,對於大多數值都一樣的情況,需要將對於的形參定義成預設形參。

4、可變長引數:可變長指的是引數的個數可以不固定。實參有按位置定義的實參 和 按關鍵字定義的實參,所以可變長的實參指的就是按照這兩種形式定義的實參個數可以不固定,然而實參終究是要給形參傳值的,所以形參必須要有兩種對應的解決方案來分別處理以上兩種形式可變長度的實參

foo(1,2)
foo(1,2,3)
foo(1,2,3,4)

foo(x=1,y=2)
foo(x=1,y=2,z=3

形參包含*/**

*會將溢位的位置實參全部接受,然後儲存成元組的形式賦值給args

def foo(x,y,z,*args):
    print(x,y,z)
    print(args)
foo(1,2,3,4,5,6)
>>>123
>>>(4,5,6)
**會將溢位的關鍵字實參全部接受,然後儲存成字典的形式賦值**後面的變數中
def foo(x,y,z,**kwargs):
    print(x,y,z)
    print(kwargs)
foo(x=1,y=2,z=3,d=4,f=5,e=6)
>>>1 2 3
>>>{'d': 4, 'f': 5, 'e': 6}

實參裡包含*/**

*:一旦碰到實參加*,打散你傳入的容器型別

def foo(x,y,z,*args):
    print(x,y,z)
    print(args)
foo(1,2,3,*[4,5,6])     #--->foo(1,2,3,4,5,6)
>>>1 2 3
>>>(4, 5, 6)
**:一旦碰到實參加**,就把字典打散成關鍵字引數傳入形參

#定義函式
def test(*args, **kwargs):
    print(args)
    print(kwargs)
#定義一個元組和一個字典
tuple = (1,2,3,4,5)
dict = {'a':1,'b':2,'c':3}
#tuple和dict兩個引數會作為一個元組傳遞給*args引數,而沒有實參傳遞給**kwargs引數。
test(tuple,dict)
>>>((1, 2, 3, 4, 5), {'a': 1, 'b': 2, 'c': 3})
>>>{}
#打散傳參
test(*tuple, **dict)  #test(1,2,3,4,5,a=1,b=2,c=3)
>>>(1, 2, 3, 4, 5)
>>>{'a': 1, 'b': 2, 'c': 3}

組合使用:如果一個函式的形參為*args與**kwargs,那麼代表該函式可以接收任何形式、任意長度的引數

def wrapper(*args,**kwargs):
    print(args)
    print(kwargs)
wrapper(1,2,3,4,5,6,x=6666,y=2222)
>>>(1, 2, 3, 4, 5, 6)
>>>{'x': 6666, 'y': 2222

5、命名關鍵字引數(瞭解)
格式:在後面的引數都是命名關鍵字引數
特徵:
後定義的引數,必須被傳值(有預設值的除外),且必須按照關鍵字實參的形式傳遞

def index(x, y, z, a=1, *args, b, **kwargs):
    print(x, y, z)
    print(a)
    print(args)
    print(b)
    print(kwargs)

index(1, 2, 3,354353, 4342, 3213123, b=222, c=333, d=444)
輸出結果:
1 2 3
354353
(4342, 3213123)
222
{'c': 333, 'd': 444}