菜雞自學 Python 筆記(三)
- 九.函式
- 1.內置函式
- 2.自定義函式
- 3.帶引數的函式
- 4.函式的回傳值
- 十.處理例外和錯誤
- 1.例外捕捉
- 2.拋出例外
- 3.自定義例外
- 十一.類與物件
- 1.創建類和實體物件
- 2.屬性的公有、私有
- 3.魔法方法
- 4.繼承
- (1)繼承
- (2)多重繼承
- (3)解決繼承中的問題
- (4)繼承中一些相關函式
九.函式
函式是組織好的,可重復使用的,用來實作單一,或相關聯功能的代碼段,
函式能提高應用的模塊性,和代碼的重復利用率,
1.內置函式
| 內置函式 | 作用 | 例子 |
|---|---|---|
| abs(x) | 回傳數值x的絕對值,如果x是復數,則回傳該值, | print(abs(-3.14)) # 3.14 print(abs(1+2j)) #2.23606797749979 |
| chr(i) | i是ASCII字符碼 0~ 255,函式回傳數值i的單字符字串, | print(chr(97)) # 'a' |
| ord() | 與chr()相反 | print(ord('a')) # 97 |
| complex(real[,imag]) | 創建一個復數 | print(complex(1,2)) #(1+2j) |
| dir([object]) | 不帶引數時,回傳當前范圍內的變數、方法和定義的型別串列;帶引數時,回傳引數的屬性、方法串列, | import sys print(dir(sys)) print(dir()) |
| divmod(a,b) | 以元組的形式回傳a除以b的商與余數 | print(divmod(8,2)) # (4,0) |
| eval(expression[, globals[, locals]]) | 執行一個字串運算式,并回傳運算式的值, | print('3*4') # 3*4 print(eval('3*4')) # 12 |
| float(x) | 將x轉化為浮點型 | print(float('10')) # 10.0 |
| pow(x,y[,z]) | 回傳 x 的 y 次方 的值,如果 z 在存在,回傳 pow(x,y) %z, | print(pow(2,2)) #4 print(pow(2,2,3)) #1 |
| tuple(sequence) | 創建一個元組物件 | print(tuple([1,2,3])) # (1,2,3) print(tuple('Asu')) # ('A', 's', 'u') |
2.自定義函式
格式:
def 函式名(引數串列):
函式體
舉例:
# 自定義函式
def say_hi():
print('Hi there!')
print('Wish to you!') # 在我們定義函式時,結尾要留有兩個空行
print("Start")
say_hi() # 先定義后使用
print("Finish")

3.帶引數的函式
在使用函式時,我們具有形參和實參的概念,
形參:形式上的引數,就像在定義函式時括號里的引數,它代表引數,但不知道具體的值,
實參:呼叫函式時的引數,具體的引數,
例如,以下,我們在say_hi()函式中傳入一個“name”引數:
def say_hi(name):
print(f'Hi {name}!')
print('Wish to you!')
say_hi("Asu")
say_hi("Dodo")

- 這里我們需要注意傳參時的位置引數和關鍵字引數
位置引數:依照引數的排列順序,絕對其對應的值
關鍵字引數:直接設定引數的名稱和值,可以不依照順序
def say_hi(name1, name2):
print(f'Hi {name1}! Hi {name2}!')
say_hi("Asu", "Dodo")
say_hi(name2='Asu', name1='Dodo')

4.函式的回傳值
return陳述句代表函式的退出,并向呼叫方回傳一個或多個值或一個運算式,
def square(number):
return number * number
print(square(4))
# 16
回傳多個值:
def num(x,y):
return x,y
print(num(4,8))
# (4,8) 以元組的形式回傳
如果函式沒有回傳值,則會回傳 None,
十.處理例外和錯誤
對于我們這樣的初學者,紅色報錯,我們會經常遇到,雖然bug很討厭,但是我們也要學會去處理解決這些討厭的家伙,
我們常見的有語法錯誤(如,少寫了:,搞錯了縮進等的)和例外(如,除以零等等),
1.例外捕捉
下面我們可以用try /except陳述句來處理這些例外,
- 這樣當用戶輸入一個錯誤的值時,系統不會直接崩潰報錯,而是輸出你想輸出的提示,
格式:
try:
執行陳述句
except 例外型別:
例外時執行陳述句
try 陳述句按照如下方式作業;
- 首先,執行 try 子句(在關鍵字 try 和關鍵字 except 之間的陳述句),
- 如果沒有例外發生,忽略 except 子句,try 子句執行后結束,
- 如果在執行 try 子句的程序中發生了例外,那么 try 子句余下的部分將被忽略,如果例外的型別和 except 之后的名稱相符,那么對應的 except 子句將被執行,
- 如果一個例外沒有與任何的 except 匹配,那么這個例外將會傳遞給上層的 try 中,
例如:
try:
age = int(input('Age: '))
income = 20000
risk = income/age
print(age)
except ValueError: # 型別錯誤
print('Invalid value')
except ZeroDivisionError: # 除法錯誤
print('Age cannot be 0')


除了try /except陳述句,我們還可以用try/except…else陳述句
try:
執行陳述句
except 例外型別:
例外時執行陳述句
else:
沒有例外時執行陳述句
try-finally 陳述句(也常用來清除例外)
try:
執行陳述句
except 例外型別:
例外時執行陳述句
else:
沒有例外時執行陳述句
finally:
不管有沒有例外都會執行的陳述句
2.拋出例外
raise陳述句 拋出一個指定的例外,
格式:raise [Exception [, args [, traceback]]]
raise 唯一的一個引數指定了要被拋出的例外,它必須是一個例外的實體或者是例外的類(也就是 Exception 的子類),
如果你只想知道這是否拋出了一個例外,并不想去處理它,那么 raise 陳述句是最佳的選擇,
x = 10
if x > 5:
raise Exception(f'x 不能大于 5,x 的值為: {x}')

3.自定義例外
內置例外通常是定義在exceotions 模塊中,解釋器啟動時,該模塊就會加載,而自定義例外,必須繼承內置例外,或者說由內置例外派生而來,
class NameError(Exception): # 定義例外
pass # 繼承
try :
raise NameError() # 拋出例外
except NameError: # 捕捉例外
print("Name!")
# Name!
十一.類與物件
物件是類的實體化,物件 = 屬性+方法,
而我們又把具有相同屬性及相同行為的一組物件稱為類,
1.創建類和實體物件
如下,我們用關鍵字class來創建一個簡單的類:
class Cat:# 類名以大寫字母開頭
# 屬性
name = "Dodo"
age = 2
weight = 5
is_lazy = True
# 方法
def talk(self):
print(f"miao~ I am {self.name}.")
cat1 = Cat() # 創建實體物件
cat1.talk() # 呼叫類中的方法
- 這里的self 用于在物件內指向物件本身,Python中的self其實跟C++的this一樣,都是代表物件本身,
- 而這里我們訪問物件的某個屬性時,可以用object.attribute的格式,即物件.屬性,
2.屬性的公有、私有
一般的屬性默認為公有,而將其變為私有也很簡單,就是在屬性名前加下劃線,
私有則意味著不能進行外部訪問,但是如果一定要去訪問它,也不是沒有辦法,我們可以定義一個內部函式,對其進行內部訪問,
# 私有,公有
class Cat:
name = "Dodo" # 公有
__age =2 # 私有 在變數名前加下劃線
def get_age(self):
return self.__age
cat1 = Cat()
print(cat1.name) # 公有可以訪問
# print(cat1.__age) # 私有不能外部訪問 ,會報錯!
print(cat1.get_age()) # 利用一個方法內部訪問
3.魔法方法
首先,先介紹一個特殊的方法,構造方法 __ init __ (self),即在創建物件時自動呼叫的一個函式,
# 魔法方法
class Cat:
def __init__(self,name): # 建構式,在創建實體的同時自動呼叫該函式
self.name = name
def talk(self):
print(f"miao~ I am {self.name}.")
cat1 = Cat("Dodo") # 傳參
cat1.talk()
# miao~ I am Dodo.
除了這個,我們還有多種多樣的魔法方法,如
__ del__ : 解構式,釋放物件時使用
__ repr__ : 列印,轉換
__ setitem__ : 按照索引賦值
__ getitem__: 按照索引獲取值
__ len__: 獲得長度
__ cmp__: 比較運算
__ call__: 函式呼叫
__ add__: 加運算
__ sub__: 減運算
__ mul__: 乘運算
__ truediv__: 除運算
__ mod__: 求余運算
__ pow__: 乘方
等等,
詳細可以看鏈接: Python中的魔術方法詳解
介紹.
4.繼承
面向物件程式主要有三個特性:
- 封裝性:資料能通過一組介面函式來存取,經過封裝的資料能夠確保資訊的隱秘性,
- 繼承性:子類繼承了其父類的成員變數與類方法,
- 多型性:多型允許一個函式有多種不同的介面,依照呼叫函式使用的引數,讓類值得使用哪一種介面,
(1)繼承
繼承的新類又叫子類、派生類、衍生類,而舊類又稱父類、基類、超類,
下面舉個例子,就很容易理解:
class Dad:
def fun(self):
print("Dad's function")
class Kid(Dad): # class 子類(父類)
pass
d=Dad()
d.fun()
k=Kid() # 子類沒有直接寫出方法,但是在繼承父類之后,也可以呼叫該方法,
k.fun()

這里需要注意,如果子類重寫父類的方法或屬性,就會把父類的方法覆寫,
class Dad:
def fun(self):
print("Dad's function")
class Kid(Dad):
def fun(self):
print("Kid's function")
d=Dad()
d.fun() # 父類并不會被覆寫
k=Kid()
k.fun()

(2)多重繼承
子類不止可以繼承一個父類,它可以進行多重繼承:
class Base1:
def fool1(self):
print("Base1: fool1")
class Base2:
def fool2(self):
print("Base2: fool2")
class Base3:
def fool3(self):
print("Base3: fool3")
class C(Base1,Base2,Base3):
pass
c= C()
c.fool1()
c.fool2()
c.fool3()

(3)解決繼承中的問題
在上面我們說過,如果子類重寫父類的方法或屬性,就會把父類的方法覆寫,如下例子,我們在寫子類的建構式時,會把繼承的父類建構式覆寫,導致子類無法訪問到父類的is_happy屬性,
# 如下報錯
class Dad:
def __init__(self):
self.is_happy=True
def happy(self):
if self.is_happy:
print("what is a happy day!")
class Kid(Dad):
def __init__(self):
self.homework_finished=True
def homework(self):
if self.homework_finished:
print("Yeah!")
d=Dad()
d.happy()
k=Kid()
k.homework()
k.happy() # 報錯
那我們要如何解決它呢?這里有兩個方法,
# 1.呼叫未系結的父類方法
class Dad:
def __init__(self):
self.is_happy=True
def happy(self):
if self.is_happy:
print("what is a happy day!")
class Kid(Dad):
def __init__(self):
Dad.__init__(self) # 這里self也是子類的實體物件
self.homework_finished=True
def homework(self):
if self.homework_finished:
print("Yeah!")
d=Dad()
d.happy()
k=Kid()
k.homework()
k.happy()
# 2.使用super函式
# 如果要修改父類,就只需要修改()里父類的名字就好,很方便
class Kid(Dad):
def __init__(self):
super().__init__()
self.homework_finished=True
def homework(self):
if self.homework_finished:
print("Yeah!")
(4)繼承中一些相關函式
- issubclass(class, classinfo) 用于判斷引數 class 是否是型別引數 classinfo 的子類,如果 class 是 classinfo 的子類回傳 True,否則回傳 False,
- isinstance(object, classinfo) 判斷一個物件是否是一個已知的型別,類似 type(),如果物件的型別與引數二的型別(classinfo)相同則回傳 True,否則回傳 False,
# issubclass
class A:
pass
class B(A):
pass
class C:
pass
print(issubclass(B,A)) # True
print(issubclass(B,B)) # True
print(issubclass(C,A)) # False
# isinstance
a1=A()
print(isinstance(a1,A)) # True
print(isinstance(a1,B)) # False
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/273240.html
標籤:python
上一篇:爬蟲實習生面試題
