Python語法進階

前言

從今天開始,我就不用“學習之路”這個標題了,感覺突出不了重點,都沒啥人看啊!前面我們已經學習了Python的基礎語法,瞭解了Python的分支結構,也就是選擇結構、循環結構以及函數這些具體的框架,還學習了列表、元組、字典、字符串這些Python中特有的數據結構,還用這些語法完成了一個簡單的名片管理系統。下面我就將介紹一下Python的一些進階語法規則,爲後面更復雜的編程打下基礎。

引用

引用這個名詞相信學過C語言和C++指針的同學應該有點印象,引用和指針還是一個很容易被混淆的概念。簡單來說,引用是一個變量,是另外一個你想被引用的變量的別名,就像是你給某個人起的一個外號,你用這個外號來代替他的名字來稱呼他,類似於一個副本。在Python中,變量和數據是分開存儲的,數據保存在內存中的一個位置,變量中保存數據在內存中的地址。變量中記錄數據的地址,就叫做引用。下面是在終端中運行ipython這個Python的交互式窗口,其中id()函數是返回對象的內存地址。
在這裏插入圖片描述
a = 1實際上就是將a這個標籤貼在1上,b = a同樣也是把b這個標籤貼在1上,所以b和a都是1的引用,當a = 2時,a這個標籤就會貼在2上,然而b不會因爲b = a這個語句發生變化,其任然是1的引用。

def test(num):
    print("在函數內部 %d 對應的內存地址是 %d " % (num, id(num)))
    # 1.定義一個字符串變量
    result = "hello"
    print("函數要返回數據的內存地址是 %d " % id(result))
    # 2.將字符串變量返回,返回的是數據的引用,而不是數據本身
    return result
# 1.定義一個數字的變量
a = 10
# 數據的地址本質上就是一個數字
print("a 變量保存數據的內存地址是 %d" % id(a))
# 2.調用test函數,本質上傳遞的是實參保存數據的引用,而不是實參保存的數據
# 注意:如果函數有返回值,但是沒有定義變量接收
# 程序不會報錯,但是無法獲得返回結果
r = test(a)
print("%s 的內存地址是 %d" % (r,id(r)))


# 輸出結果
a 變量保存數據的內存地址是 10914784
在函數內部 10 對應的內存地址是 10914784 
函數要返回數據的內存地址是 139989701883752 
hello 的內存地址是 139989701883752

局部變量和全局變量

簡而言之,局部變量就是在函數內部定義的變量,只能在函數內部使用(後面會學類,在類內部使用),在函數外部不可被發現,不可被使用。全局變量就是定義在模塊內,在所有的函數、類的外面。
局部變量:

def demo1():
    # 定義一個局部變量
    # 1.出生:執行了下方的代碼之後,纔會被創建
    # 2.死亡:函數執行完成之後
    num = 10
    print("在demo1函數內部的變量是 %d" % num)
def demo2():
    num = 99
    print("%d" % num)
    pass
# 在函數內部定義的變量,不能在其他位置使用
# print(num)  這裏如果這樣寫的話會報錯
demo1()
demo2()


# 運行結果
在demo1函數內部的變量是 10
99

全局變量:

# 全局變量
num = 10
def demo1():
    print("demo1 ==> %d" % num)
def demo2():
    print("demo2 ==> %d" % num)
demo1()
demo2()

# 運行結果
demo1 ==> 10
demo2 ==> 10

函數不能修改全局變量的值,因爲函數是處於局部之內,但是如果函數想修改全局變量的話可以將變量前聲明成global,這樣這個變量就變成了全局變量。global 關鍵字會告訴解釋器後面的變量是一個全局變量,再使用賦值語句時就不會創建局部變量。我們在開發程序時,應該將所有的全局變量放在代碼開始的地方,也就是先導入包和模塊,再就是定義全局變量,這樣在後面使用的時候就不會出問題。

函數多個返回值

Python函數可以有多個返回值,當有多個返回值時,其返回的數據類型是元組,可以使用多個變量來接收元組裏的數據,但要保持數量一致。

def measure():
    """測量溫度和溼度"""
    print("測量開始...")
    temp = 39
    wetness = 50
    print("測量結束...")
    # 元組-可以包含多個數據,因此可以使用元組讓函數一次返回多個值
    # 如果函數返回的類型是元組,小括號可以省略
    # return (temp,wetness)
    return temp,wetness
# 元組
result = measure()
print(result)
# 需要單獨的處理溫度或溼度-不方便
print(result[0])
print(result[1])
# 如果函數返回的類型是元組,同時希望單獨的處理元組中的元素
# 可以使用多個變量,一次接收函數的返回結果
# 注意:使用多個變量接收結果時,變量的個數應該和元組中元素的個數保持一致
gl_temp, gl_wetness = measure()
print(gl_temp)
print(gl_wetness)

# 運行結果
測量開始...
測量結束...
(39, 50)
39
50
測量開始...
測量結束...
39
50

交換變量

學C語言的時候肯定遇到過一個題目叫你交換兩個變量的值,冒泡排序的時候就會用到,什麼t = a[j];a[j] = a[j+1];a[j+1] = t;這樣的東西,轉來轉去是不是賊麻煩。Python中有一種特有的方法來交換兩個變量的值:a, b = (b, a) 就這麼一個語句就可以交換a,b兩個變量的值。

可變參數和不可變參數

在函數內部,針對參數使用賦值語句,不會修改到外部的實參變量;但是如果使用的是方法,也就是函數,可以修改實參變量。

def demo(num, num_list):
    print("函數內部的代碼")
    num = 100
    num_list = [1, 2, 3]
    print(num)
    print(num_list)
    print("函數執行完成")
gl_num = 99
gl_list = [4, 5, 6]
demo(gl_num, gl_list)
print(gl_num)
print(gl_list)

# 運行結果
函數內部的代碼
100
[1, 2, 3]
函數執行完成
99
[4, 5, 6]

def demo(num_list):
    print("函數內部的代碼")
    # 使用方法修改列表的內容
    num_list.append(9)
    print(num_list)
    print("函數執行完成")
gl_list = [1, 2, 3]
demo(gl_list)
print(gl_list)

# 運行結果
函數內部的代碼
[1, 2, 3, 9]
函數執行完成
[1, 2, 3, 9]

函數的缺省參數

前面講列表那一塊的時候有介紹到sort()函數,默認是升序排序,如果添加一個參數sort(reverse=True)的話就是降序排序了,這裏sort函數中的reverse就是一個缺省參數,默認有缺省值。函數在定義時,如果某個參數設置了默認值,那麼在調用這個函數的時候,想默認使用的話就可一不用傳遞參數,如果傳遞參數的話,就會修改默認值。在指定缺省參數的默認值時,應該使用最常見的值作爲默認值。

def print_info(name,gender = True):
	"""
    :param name: 班上同學的姓名
    :param gender: True 男生 False 女生
    """
    gender_text = "男生"
    if not gender:
        gender_text = "女生"
    print("%s是%s" % (name,gender_text))
# 假設班上的同學,男生居多
# 提示:在指定缺省參數的默認值時,應該使用最常見的值作爲默認值
print_info("小明")
print_info("老王")
print_info("小美", False)

多值參數

當一個Python函數想要接收不定個數的參數時就可以使用多值參數。多值參數有兩種:一種是參數前面加一個*;另一種是參數前面加兩個*。例如:*args:存放元組參數;**kwargs:存放字典參數。
在這裏插入圖片描述
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20200306153243421.png在這裏插入圖片描述

def demo(num, *nums, **person):
    print(num)
    print(nums)
    print(person)
demo(1)
demo(1, 2, 3, 4, name="小明", age=18)

# 運行結果
1
()
{}
1
(2, 3, 4)
{'name': '小明', 'age': 18}

num是默認是一個數字變量,所以輸出一個1;*nums是元組,輸出爲(2, 3, 4);**person是字典,輸出爲{‘name’: ‘小明’, ‘age’: 18}。
多值參數求和:

def sum_numbers(*args):
    num = 0
    print(args)
    # 循環遍歷
    for n in args:
        num += n
    return num
result = sum_numbers(1, 2, 3)
print(result)

# 運行結果
(1, 2, 3)
6

元組和字典的拆包

在調用帶有多值參數的函數時,如果希望將一個元組變量傳遞給args,將一個字典變量傳遞給kwargs,就可以選擇拆包,簡化參數傳遞,也就是告訴函數,我這裏的哪一部分是元組,我要你全部輸出,那一部分是字典,再全部輸出,相當於打了一個包。

def demo(*args, **kwargs):
    print(args)
    print(kwargs)
# 元組變量/字典變量
gl_nums = (1, 2, 3)
gl_dict = {"name": "小明", "age": 18}
# demo(gl_nums, gl_dict)
# 拆包語法,簡化元組變量/字典變量的傳遞
demo(*gl_nums, **gl_dict)
demo(1, 2, 3,name="小明", age=18)

# 運行結果
(1, 2, 3)
{'name': '小明', 'age': 18}
(1, 2, 3)
{'name': '小明', 'age': 18}

遞歸函數

大家學過C語言的應該都瞭解一點遞歸,遞歸函數就是函數自己調用自己,在自己調用自己的時候,要給出遞歸的出口,不然函數就會一直執行下去,成了個死循環。有時候解決複雜問題時可以選擇遞歸,但是有的時候遞歸會佔用過多的內存和時間。

def sum_number(num):
    print(num)
    # 遞歸的出口,當參數滿足某個條件時,不再執行函數
    if num == 1:
        return
    # 自己調用自己
    sum_number(num-1)
sum_number(3)

# 運行結果
3
2
1

最後

訪問量破千,一起加油!

寫博客是爲了記錄和分享自己的學習歷程,溫故知新!做的不好的地方歡迎指正!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章