Python學習示例源碼


函數和函數式編程

  • 函數定義;

  • 函數調用;

  • 過程定義;

  • 過程調用;

  • 面向過程的編程方法;

"""
面向對象-----類------class
面向過程-----過程---- def
函數式編程----函數----def

函數定義:將一組語句的集合通過一個名字(即函數名)封裝起來,要想執行這個函數,只需調用其函數名即可


函數和過程都是可以調用的,過程就是一個沒有返回值的函數而已

面向過程的編程方法:一段一段的邏輯或者一段一段的功能包含在def定義的過程中,使用時直接調用
函數式編程:?
"""


# 語法定義
# 定義一個函數,有返回值
def func1():   # 函數名,括號里可以寫入參數
    """testing"""
    print('in the func1')  # 函數體,表示復雜邏輯的代碼
    return 0  # 返回值


# 定義一個過程,沒有返回值
def func2():
    """testing2"""
    print("in the func2")  # 表示復雜邏輯的代碼

# 調用
x = func1()
y = func2()
print('from func1 return is %s' %x)
print('from func2 return is %s' %y)  # 也被當成了一個隱式的函數

示例:使用函數減少重復代碼

為什么要使用函數:

1.減少重復代碼

"""
為什么要使用函數:減少重復代碼;使程序變得可擴展;使程序變得易維護
日志文件處理(框架搭建必須有的)
"""
import time


def logger():

    with open('a.txt', 'a+') as f:
        f.write('end action\n')       # 類似寫日志文件


# 模擬一個功能,並將日志文件寫入日志文件
def test1():
    """文檔描述"""
    print('in the test1')  # 日志追加
    logger()      # 寫入日志


# 模擬另外一個功能
def test2():
    print('in the test2')  # 日志描述
    logger()  # 寫入日志


# 模擬第三個功能
def test3():
    print('in the test3')
    logger()  # 寫入日志

# 調用各個功能模塊
test1()
test2()
test3()

示例:使用函數使程序變得可擴展

2.使程序變得可擴展

"""
為什么要使用函數:減少重復代碼;使程序變得可擴展;使程序變得易維護
日志文件處理(框架搭建必須有的)
"""
import time


def logger():
    time_format = '%Y-%m-%d %X'  # 年月日,時分秒
    time_current = time.strftime(time_format)
    with open('a.txt', 'a+') as f:
        f.write('%s end action\n' % time_current)       # 類似寫日志文件


# 模擬一個功能,並將日志文件寫入日志文件
def test1():
    """文檔描述"""
    print('in the test1')  # 日志追加
    logger()      # 寫入日志


# 模擬另外一個功能
def test2():
    print('in the test2')  # 日志描述
    logger()  # 寫入日志


# 模擬第三個功能
def test3():
    print('in the test3')
    logger()  # 寫入日志

# 調用各個功能模塊
test1()
test2()
test3()

 

示例:函數返回值

編寫函數為什么要有返回值,作用:想要這個函數的執行結果。

函數體中可以是一行代碼,也可以是一萬行代碼。這個函數執行的結果是什么,我后面的程序需要這個程序的返回結果。

"""
函數返回值
函數返回值的作用:后面的程序需要這個函數的返回結果
"""


def test1():
    """未定義返回值"""
    print('in the test1')  # 函數體


def test2():
    '''定義返回值'''
    print('in the test2')  # 函數體
    return 0  # 定義返回值,結束函數的效果


def test3():
    '''定義返回值有數字,字符,元組,字典'''
    print('in the test3')  # 函數體
    return 1, 'hello', ['zhangsan', 'lisi'], {'name': 'emy'}

x = test1()  # 函數體的返回值
y = test2()  # 函數體的返回值
z = test3()  # 函數體的返回值
print(x)
print(y)
print(z)

示例:帶參數的函數

學會以下傳參方法:位置參數;默認參數;參數組傳參;字典參數傳參

"""
帶參數的函數:關鍵字參數和位置參數
關鍵參數不能寫在位置參數前面
"""


def test(x, y):
    print(x)
    print(y)

test(5, 8)  # 位置參數與形參一一對應
test(x=1, y=6)  # 關鍵字參數與形參順序無關
test(y=9, x=3)  # 關鍵字參數與形參順序無關


# 默認參數
def test1(x, y=2):
    print(x)
    print(y)

test1(1)
test1(1, y=3)

# 默認參數特點:調用函數時默認參數可有可無,不是必傳參數
# 默認參數應用場景:占位或默認初始設置路徑或默認端口3306

示例:參數帶參數組的函數定義方式

# 參數組*args:實參不固定的情況下,怎么定義實參,在這種情況下,采用參數組,接收N個位置參數,不是關鍵字方式,轉換成元組的方式;
# 應用場景:給函數傳不固定的參數,定義參數時,根據業務發展,可能有預想參數個數不一樣的的情況下
# 規范:*args ,如果星號后面采用其他名字,程序不會報錯,但是最后用規范的帶args名,這樣便於閱讀
def test2(*args):
    print(args)

test2(1, 2, 3, 4, 5)
test2(*[1, 2, 3, 4, 5, 6])  # args=tuple(1,2,3,4,5,6)


def test3(x, *args):
    print(x)
    print(args)

test3(1, 2, 3, 4, 5, 6, 7)

示例:參數帶字典的函數定義方式

# **kwargs接收N個關鍵字參數,轉換成字典的形式


def test2(**kwargs):
    print(kwargs)
    print(kwargs['name'])
    print(kwargs['age'])
    print(kwargs['sex'])


test2(name='zhangsan', age=8, sex='male')
test2(**{'name': 'zhangsan', 'age': '22', 'sex': 'male'})

示例:參數可擴展的函數定義方式

# 參數可擴展的函數


# 與位置參數一起使用
def test3(name, **kwargs):
    print(name)
    print(kwargs)

test3('zhangsan')  # 這樣轉參數,會接收一個name和一個空字典----->>正確
test3('lisi', age=8, sex='male')  # 與位置參數結合,以關鍵字方式傳參------>>正確


# 與默認參數一起使用
def test4(name, age=8, **kwargs):  # 默認參數不能寫在參數最后,參數組置后
    print(name)
    print(age)
    print(kwargs)

test4('wangwu', sex='male', hobby='study', age=3)   # 此處的age傳參可以寫在最后,也可以寫在對應的位置


# 所有類型的參數結合在一起(位置參數,默認參數,帶數組的參數,帶字典的參數)
def test5(name, age=18, *args, **kwargs):
    print(name)
    print(age)
    print(args)
    print(kwargs)

test5('amy', age=28, sex='male', hoddy='study')  # 在這個沒有位置參數,所以*args在運行的時候接收為空元組;后面兩個參數為兩個關鍵字參數。所以傳給**kwargs

函數和函數式編程:不是同一種方式,了解就行,不用深究

函數式編程、面向過程、面向對象編程是三種編程范式。函數式編程是一種抽象很高的一種編程范式,輸入是什么輸出就是什么,函數是輸入和輸出可以不同。

如有疑問,可加入QQ學習群:484601288

​局部變量和與全局變量

​是否可在一個函數中引用另外一個函數呢?

示例:局部變量

# 局部變量:函數里面的變量即為局部變量,只在函數里有效
        
        
def change_name(name):
    print("befor change", name)
    name = 'San Zhang'  # 這個函數就是這個變量的作用域
    print("after change", name)
        
name = 'zhangsan'
change_name(name)
print(name)

示例:全局變量

# 全局變量:在整個程序中都生效的變量,在整個代碼的頂層定義的變量就是全局變量
       
company = 'ali'
       
       
def change_name(name):
    company = 'tengxu'
    print("befor change", name, company)
    name = 'zhangsan'  # 這個函數就是這個變量的作用域
    print("after change", name)
       
print(company)
       
name = 'lisi'
change_name(name)
print(name, company)

示例:局部變量改為全局變量1

在函數里面,默認情況下“字符串”和“常量”,這兩類局部變量不能更改全局變量,如果想在函數中將局部變量改為全局變量的方法:改之前申明global,不建議使用這種方法。

# 在函數里面,默認情況下局部變量不能更改全局變量,如果想在函數中將局部變量改為全局變量的方法:改之前申明global,不建議使用這種方法
       
company = 'ali'  # 全局變量
       
       
def change_name(name):
    global company
    company = 'tengxu'    # 局部變量
    print("befor change", name, company)
    name = 'zhangsan'  # 這個函數就是這個變量的作用域
    print("after change", name)
       
print('company: ', company)   # 執行查看函數調用前打印的情況
name = 'lisi'
change_name(name)
print(name)
print('company: ', company)   # 執行查看函數調用后打印的情況

示例:局部變量改為全局變量2

未像<局部變量改為全局變量1>那樣申明global,也將局部變量更改為全局變量了。所以默認不能更改只針對“字符串和整數”外。復雜的數據類型:列表,類,字典,集合都是可以將局部變量改為全局變量。

# 局部變量改全局變量
    
company = 'ali'  # 全局變量
names = ['zhangsan', 'sili', 'wangwu']
    
    
def change_name():
    names[0] = '張三'
    print("inside_func: ", names)          # 運行查看執行結果
    
change_name()
print('ouside_func:', names)   # 運行查看執行結果

示例:作死的全局變量定義

或許你在其他地方也會看見這種方式,忘掉這種方式,不能使用這種方法,這種在邏輯復雜的代碼中不利於調試,盡管是自己寫的代碼也會如此。

# 不建議使用這種方法
def chang_name():
    global name
    name = 'zhangsan'
     
chang_name()
print(name)

示例:使用遞歸方式實現,傳一個值,每次除以2直到不能除為止

遞歸特性:1、必須有一個明確的結束條件;2、每次進入更深一層遞歸時,問題規模相比上次遞歸都應有減少;3、遞歸效率不高,可能會導致內存資源耗盡

做遞歸最好的運行方式,采用斷點方式調試。

簡單的一個遞歸方式實現傳一個值,每次除以2直到不能除為止:

# 傳一個值,每次除以2直到不能除為止
  
def calc(n):
    print(n)
    if int(n/2)>0:
        return calc(int(n/2))
    print('--->>', n)
  
calc(10)

所有示例程序均在Ubuntu16.04系統下的python3.5下成功執行。

高階函數:變量可以指向函數,函數的參數能接收變量,那么一個函數就可以接收另一個函數作為參數

# 把一個函數當成一個參數傳給另一個函數,這個函數就是高階函數


# 這是一般普通的函數
def add(a, b):
    return a + b


# 高階函數
def add(a, b, f):
    return f(a) + f(b)

res = add(3, -6, abs)
print(res)

如有疑問,可加入QQ學習群討論:484601288


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM