天天看點

從零學python必備知識(一、函數+類)(附示例代碼)

文章目錄

    • 1、疊代器
    • 2、lambda表達式
    • 3、内建函數filter,map,reduce,zip
    • 4、閉包的定義
    • 5、閉包的使用
    • 6、裝飾器
    • 7、上下文管理器(附異常捕獲)
    • 8、子產品的定義
    • 9、PEP8編碼規範
    • 10、類與執行個體
    • 11、增加類的屬性與方法(附類封裝特性)
    • 12、類的繼承(附多态)
    • 13、類的使用(自定義with語句)
    • (二)、并發與正規表達式
    • (三)、機器學習庫

python安裝、資料類型、函數及變長參數等基本知識不再贅述,下面從最基礎的疊代器開始學習。

(這篇主要是函數與類相關的知識)

1、疊代器

#樣例1iter
list1 = [1,2,3]
it = iter(list1)
print(next(it))
print(next(it))
           
#樣例2yield---生成器,疊代器的一種
def frange(start,stop,step):
    x = start
    while x<stop:
        yield x#暫停以記錄x的值
        x+= step
for i in frange(10,20,0.5):
    print(i)
           

2、lambda表達式

#lambda表達式前面是參數,後面是return内容
def true():
    return True##複雜,可使用lambda表達式簡化
lambda : True

def add(x,y):
    return x+y
lambda x,y: x+y

def func(x):
    return x<=1
lambda x:x<=1
           

3、内建函數filter,map,reduce,zip

a = [1,2,3,4,5]
b = [6,7,8,9,10]
#filter選出a中滿足函數要求的數,傳回filter對象
print(list(filter(lambda x: x > 2, a)))

#map對比較參數依此處理,傳回的是map對象
print(list(map(lambda x: x+1, a)))
print(list(map(lambda x, y: x+y, a, b)))#實作a,b中每個元素依次相加,輸出[7, 9, 11, 13, 15]

from functools import reduce
print(reduce(lambda x, y: x*y, [2,3,4], 1))#4*((1*2)*3)=24

for i in zip((1,2,3), (4,5,6)):
    print(i)#這裡的作用類似于矩陣,輸出(1, 4)(2, 5)(3, 6)
dicta = {'a': 'aa', 'b': 'bb'}
dictb = zip(dicta.values(), dicta.keys())#相當于将字典的key和value對調,傳回的是zip類型
print(dict(dictb))#轉換為dict後輸出,{'aa': 'a', 'bb': 'b'}
           

4、閉包的定義

閉包:外部函數的變量被内部函數引用的方式

例中add—函數的名稱或引用;add()函數的調用

#(觀察得一個閉包最後傳回的是内層函數的*引用or名稱*)
def sum(a):
    def add(b):
        return a+b
    return add
**#add---函數的名稱或引用;add()函數的調用**
num = sum(2)
print(num(4))#6

#閉包實作遞增的操作,傳入值就為FIRST,預設是0
def counter(FIRST=0):
    cnt = [FIRST]
    def add_one():
        cnt[0] +=1
        return cnt[0]
    return add_one

num5 = counter(5)#從5開始
num10 = counter(10)
print(num5())#6
print(num5())#再運作一次又加1,輸出7
print(num10())#11
print(num10())#12
           

5、閉包的使用

使用閉包的好處:調用的參數比普通函數少,代碼優雅。

#例題:解決a*x+b=y,
def a_line(a,b):
    def arg_y(x):
        return a*x+b
    return arg_y

line1 = a_line(3,5)
line2 = a_line(5,10)
print(line1(10))#35
print(line2(10))#60
           

6、裝飾器

(與閉包不同的是,閉包外層參數是數,裝飾器外層參數是函數)

優點:

  1. 調用函數時不用重複在代碼上邊下面編寫相應修飾代碼,可以放在裝飾器裡;
  2. 裝飾器的代碼複用可以用”@裝飾器名稱“來進行重複調用,文法更簡潔
#1)計時器示例
import time
def timmer(func):
    def wapper():
        start_time = time.time()
        func()
        stop_time = time.time()
        print("運作時間:%s秒"%(stop_time - start_time))
    return wapper

@timmer
def i_can_sleep():
    time.sleep(3)
#調用函數
i_can_sleep()#輸出:運作時間:3.0513498783111572秒
           
#2)實作内部函數帶參數
def tips(func):
    def nei(a,b):
        print("start!")
        func(a,b)
        print("stop!")
    return nei
@tips
def add(a, b):
    print(a+b)
@tips
def sub(a, b):
    print(a-b)

print(add(4, 5))
           

輸出:

start!

9

stop!

None

start!

2

stop!

None

#3)2的基礎上裝飾器帶參數(外層再嵌套new_tips)
def new_tips(argv):
    def tips(func):
        def nei(a, b):
            print("start! %s %s"%(argv, func.__name__))
            #func.__name__取運作的函數名稱
            func(a, b)
            print("stop!")
        return nei
    return tips
    
@new_tips("add_module")
def add(a, b):
    print(a + b)

@new_tips("sub_module")
def sub(a, b):
    print(a - b)

print(add(4, 5))
print(sub(7, 5))
           

輸出:

s tart! add_module 函數名稱:add

9

stop! None start! sub_module 函數名稱:sub

2

stop!

None

7、上下文管理器(附異常捕獲)

檔案操作是python常用操作,需要捕獲異常,正常寫法為:

try:
    a = open('name.txt')
    for line in fd:
		print(line)
except Exception as e:
    print(e)
finally:
    a.close()
           

簡化版,其中with的操作會自動調用finally中的close()的操作,優雅的多。這就是一種上下文管理器

with open("name.txt") as f:
	for line in f:
		print(line)
           

8、子產品的定義

自己編寫的函數希望下次繼續使用就可以以子產品的形式對其進行儲存。

首先兩個檔案,一個是mymod.py,定義函數等

def print_me():
	print("me!")
           

另一個檔案,mod_test.py,調用剛定義的子產品

import mymod
mymod.print_me()#輸出:me
           

9、PEP8編碼規範

有用的插件:autopep8安裝教程:

python代碼一鍵格式化,符合pep8規範

10、類與執行個體

面向對象程式設計,幾點總結:

  1. 定義類,類名首字母大寫;
  2. 引用類叫做類的執行個體化;
  3. 類中實作的函數功能叫做定義類的方法;變量稱為屬性;
  4. 是把相同的内容進行一些歸納,更符合人的思維習慣
  5. 特殊關鍵字:self:表示類執行個體化的本身(類中使用變量時必須要帶);__init__是一個特殊方法,對類進行執行個體化後會自動執行。
class Player():
    def __init__(self, name, hp):#此方法中預定義了一些功能
        self.name = name#**使用變量時必須要帶self**
        self.hp = hp
    def print_role(self):#定義一個方法
        print('%s: %s' % (self.name, self.hp))


user1 = Player('Tom', 100)#類到具體對象的過程叫類的執行個體化
user2 = Player('Jerry', 90)
user1.print_role()#示例調用方法
user2.print_role()
           

Tom: 100

Jerry: 90

11、增加類的屬性與方法(附類封裝特性)

增加一個occu職位屬性和updateName()方法。

注意:此時修改名稱除了使用updateName()還可以直接指派,例如指派’aaa’。如果将第三行的name改為__name,則隻能通過調用方法改變,不可随意指派改變 ------這稱為類的封裝!

class Player():
    def __init__(self, name, hp, occu):  # 此方法中預定義了一些功能
        self.name = name  # 使用變量時必須要帶self
        self.hp = hp
        self.occu = occu
    def print_role(self):  # 定義一個方法
        print('%s: %s %s' % (self.name, self.hp, self.occu))
    def updateName(self, newname):#修改名稱
        self.name = newname

user1 = Player('Tom', 100,'war')  # 類到具體對象的過程叫類的執行個體化
user2 = Player('Jerry', 90,'master')
user1.print_role()  
user2.print_role()
user1.updateName('Wilson')#user1改名
user1.print_role()
user1.name='aaa'#還可以直接指派
user1.print_role()
           

Tom: 100 war

Jerry: 90 master

wilson: 100 war

aaa: 100 war#此時指派是可以的

12、類的繼承(附多态)

子類可以繼承父類中的方法,當方法同名會發生覆寫;即當你使用時才能知道運作的時哪一種方法,說明方法有多種狀态,這也是面向對象的一個特性-----多态;

在下面例子中,有以下要點:

  1. 使用super,子類調用父類的__init__初始化函數,括号是需要的參數
  2. **type()**方法判斷執行個體所屬的類
  3. isinstance(a2,Monster)方法判斷a2是否屬于Monster類。在終端調式可以發現python所有的類型都是object類的子類,例如:
    從零學python必備知識(一、函數+類)(附示例代碼)
class Monster():
    def __init__(self, hp=100):  # 預設值,初始化100
        self.hp = hp

    def run(self):
        print("Move!")

class Animals(Monster):
    def __init__(self, hp=10):
        super().__init__(hp)#使用super不需要重複使用self.hp=hp

a1 = Monster(200)
print(a1.hp)
print(a1.run())
a2 = Animals(1)
print(a2.hp)
print(a2.run())
print("a1的類型:%s"%(type(a1)))
print(isinstance(a2,Monster))
           

200

Move!

None

1

Move!

None

a1的類型:<class ‘main.Monster’>

True

13、類的使用(自定義with語句)

下面的例子實際就是把類的功能和抛出異常結合起來。

exc_tb是__exit__中捕獲的異常。

#類使用,自定義with
class Testwith():
    def __enter__(self):
        print('run!')
    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_tb is None:#即沒有異常
            print('正常結束!')
        else:
            print('has error:%s'%exc_tb)#輸出錯誤

with Testwith():
    print('Test is running')
           

run!

Test is running

正常結束!

如果有異常是什麼樣?我們可以在with後面手動抛出異常(使用raise),常見的是NameError:

從零學python必備知識(一、函數+類)(附示例代碼)

(二)、并發與正規表達式

從零學python必備知識(二)

(三)、機器學習庫

從零學python必備知識(三)