Python封裝
Python函數教程

函數本身其實就相當于一個集裝箱,她負責把我們之前寫的那些代碼裝進去,她在打包的時候會在箱子的上下各開兩個透氣的口子,上面的口子叫參數,下面的口子叫返回值~~~~~(當然你也可以選擇性的關閉這兩個口子哦)
"""
python定義函數, 對代碼進行封裝,python也是引用傳遞,而不是值傳遞
1- 如果函數名一樣,python并不會報錯,而是會覆蓋
def 函數名(參數)
"""
def?my_print():
print("HAHAHHA")
def?my_print():
print("HAHAHHA22222")
for?i?in?range(5):
my_print()
# 如果提示shadows in xxx build in是因為你定義的函數名和內置的函數名一樣,比如sum()
def?my_sum(a, b):
print("a + b = %d"?% (a + b))
my_sum(1,5)
# 帶有返回值的函數, 使用 -> 的方式,和typescript類似
def?my_sum(a, b) ->?int:
return?(a + b)
print("a + b = %d"?% my_sum(1,?5))
"""
函數的嵌套調用,就是函數中調用另一個函數
1- my_func02 必須定義在My_func01之前,真正調用的時候才會加載,并不會全局預加載
2- 內置函數的作用域,不會自動調用
"""
def?my_func02():
print("C")
print("D")
def?my_func01():
print("A")
my_func02()
print("B")
my_func01()
def?my_func03():
print("A")
# 內置def函數,注意作用域, 注意內置函數不會自動調用
def?my_func04():
print("C")
my_func04()
print("D")
print("B")
my_func03()
# 函數參數的亂序位置,也可以像kotlin一樣添加關鍵字參數
# 注意:如果某個參數使用了關鍵字參數,那么之后的參數必須都必須使用關鍵字參數
# 換句話說,就是參數可以合理的一一對應,開發中一般很少使用關鍵字參數,看懂即可
def?get_info(name, age) ->?str:
return?"name: %s, age: %s"?% (name, age)
print(get_info(age=?"26",?name="張三"))
"""
缺省函數,就是參數可以有默認值,跟kotlin一樣
返回值也可以簡寫,省略 -> int:
"""
def?print_info(name, age=20):
print("姓名:%s, 年齡:%s"?% (name, age))
print_info("張三",?28)
print_info("李四")
"""
元組[]不定長參數,參數的數量不確定, 調用類似于位置參數
參數名之前加上*表示這個星號表明參數的類型為元祖,但是傳入實參的時候不需要中括號[]
"""
def?my_func01(*args):
print(type(args))
print(args[0])
my_func01(1,?3,?5)
my_func01(1,?3,?5,?7)
"""
字典類型{}的不定長參數, 調用類似于關鍵字參數name=的形式
參數名前面加上**兩個星號,表明這個參數為一個字典,傳入的時候不需要寫{},但是只能傳入一個字典
"""
def?my_func02(**kwargs):
print(type(kwargs))
print(kwargs["name"])
print(kwargs["age"])
my_func02(name="小明",?age=12)
"""
一個函數的包含多return個
"""
def?my_func03(score:?int) ->?str:
if?score >=?70:
return?"優秀"
elif?score >=?30:
return?"中性"
else:
return?"差"
print(my_func03(50))
"""
處理多個返回值的方式
1- return ["小明", 28]
2- return {"name":"小明","age":28]
2- return 返回值1, 返回值2
"""
def?my_func04(name, age):
return?name, age
print(my_func04("張三",28)[0])
print(my_func04("張三",28)[1])
"""
python中的拆包(列表,字典,多個返回值): 一次性初始化多個變量的值
如果返回值是列表,字典,或者多個返回值,可以直接用來賦值多個變量的方式就叫做拆包,簡化代碼量
"""
num01, num02, num03, num04 =?1,?3.14,?True,?"Hello World"
num05, num06, num07, num08 = [1,?3.14,?True,?"Hello World"]
name, age = my_func04("李四",?28)
print(name,?"-->", age)
"""
拆包中python快速交換兩個變量的值, 免去了temp中間值
"""
a, b =?4,?5
a, b = b, a ? ??# b的引用給a, a的引用給b,快速交換值
"""
函數中的局部變量的釋放獅是在函數執行完后就馬上消失
全局變量是等真個程序運行完后進行銷毀,作用域是整個函數
1- 如果局部變量名和全局的相同,那么執行的時候根據就近原則
2- 如果函數內找不到該變量名,那么就去找全局變量
3- 如果函數內想要就該外面的全局變量,使用globe關鍵字
"""
num =?10
def?my_func01():
# num = 20 ?這里是創建一個新的內部變量
global?num
num =?20 ? ?# 這里告訴函數并非創建新的局部變量,而是使用全局的變量操作
print("內部num = %s"?% num)
my_func01()
print("外部num = %s"?% num)
"""
函數自建函數文檔說明help(len)
如果函數內沒有自定義文檔說明,那么就返回找函數名上面一行的注釋
"""
help(len)
# 這里是沒有專門的說明進行返回的內容
def?my_func02(num01, num02):
"""
返回兩個參數的和
:param?num01: 數字1
:param?num02: 數字2
:return: 兩個數字的和
"""
return?num01 + num02
help(my_func02)
"""
id(obj)查找obj內存的物理地址引用門牌號
類似:定了一個房間但是沒有入住,調用的時候才入住
a,b指向同一個房間,節省內存
"""
a =?1000
b =?1000
c =?"abc" ??# 字符串,元祖()等不可不的數據類型,修改的話是copy重新開一個房間
d =?"abc" ??# 列表[],字典可變數據結構,修改的話是在同一個房間進行修改的。
c =?"abcd"
print(id(a))
print(id(b))
print(id(c))
print(id(d))
Python函數---遞歸專欄
這個說起來就比較煩了,簡而言之就是自己用自己。
"""
斐波那契
python中的遞歸函數, time模塊中的sleep(單位是秒s)
1- 用現有的while循環來實現
2- 遞歸實現,必須有一個停止的條件來調用自己
"""
"""
原理:
n! = {
if ? -> ?n * (n - 1)! ? if( n>=0)
else -> ?1 ? ? ? ? ? ? ?if( n=0)
}
1- f(3) -> 3*f(2)
2- f(2) -> 2*f(1)
3- f(1) -> 1*f(0)
4- f(0) -> return 1
"""
def?c_func(num):
if?num >?1:
return?num * c_func(num -?1)
else:
return?1
print(c_func(3))
"""
遞歸的核心就是將表達式分部分,重復的部分和截至的部分
遞歸求fib序列: 1 1 2 3 5 8
fib(n) = {
n = fib(n-2) + fib(n-1) ? if n>2
n = 1 ? ? ? ? ? ? ? ? ? ? else (n=1 or n=2)
}
"""
def?d_func(num):
if?num >?2:
return?d_func(num -?2) + d_func(num -?1)
else:
return?1
print(d_func(6))
"""
lambda關鍵字表示這是一個匿名函數,通過小括號來執行()
"""
# 無參數無返回值
def?f_func():
print("Hello World 1")
f_func()
a_lambda =?lambda: {
print("Hello World 2")
}
a_lambda()
(lambda: {print("Hello World 3")})()
# 無參數有返回值, lambda冒號后面不用寫return
def?e_func():
return?"Hello World 4"
print(e_func())
print((lambda:?"Hello World 5")())
# 有參數,無返回值,參數寫在lambda后面,冒號前面
def?f_func(name):
print(("Hello World 6 --> %s"?% name))
f_func("張三")
(lambda?name: {print(("Hello World 7 --> %s"?% name))})("張三")
# 有參數,有返回值
def?g_func(name):
return?"Hello World 8 --> %s"?% name
print(g_func("李四"))
print((lambda?name: {"Hello World 9 --> %s"?% name})("李四"))
"""
匿名函數lambda作為函數參數
函數內a,b進行特定操作后,最后交給callback進行回掉
"""
def?h_func(a, b, callback):
print("result = %d"?% callback(a, b))
# lambda a,b: a + b
h_func(3,?5,?lambda?a, b: a + b)
Python類教程(面向對象)
如果說函數是一個集裝箱,那么類就是一個放集裝箱的大倉庫。我們把作一類事情的函數都會放到一個類里面。這樣我們的代碼就會更加美觀,更加方便看懂。
class?Person(object):
def?__init__(self, name, age, num):
self.name = name
self.age = age
self.num = num
def?__str__(self):
return?"姓名:%s 年齡: %s 學號: %s"?% (self.name,?self.age,?self.num)
def?__del__(self):
# 監聽對象銷毀,可以用來用戶復活
print("再見")
def?print_info(self):
print("姓名:%s 年齡: %s 學號: %s"?% (self.name,?self.age,self.num))
p1 = Person("張三",?18,?1605477)
print(p1)
p2 = p1 ? ??# 引用計數+1
p3 = p1 ? ??# 引用計數+1
del?p1 ? ? ?# 引用計數-1
del?p2 ? ? ?# 引用計數-1
del?p3 ? ? ?# 引用計數=0
# input()
"""
1- 使用同一個類創建的不同對象,**屬性**是需要單獨開辟內存的,防止一損俱損
2- 但是類的自定義方法是唯一的只有一份內存, 是通過self判斷不同的調用對象是誰
"""
p4 = Person("張三",?18,?1605477)
p5 = Person("張三",?18,?1605477)
print(id(p4.name)) ? ? ? ? ? ? ?# name作為類屬性,有單獨的內存空間,id地址不同
print(id(p5.name)) ? ? ? ? ? ? ?# 但是因為小整數型原因,顯示的id相同,但原理id是不同的
print(id(p4.print_info())) ? ? ?# 類方法是唯一一份的,所以id相同
print(id(p5.print_info()))
"""
單繼承,class B(A) 括號里面的是相對B來說的B的父類,集成了A的屬性和方法
1- python中類的屬性是直接寫在init方法中的
"""
class?A(object):
def?__init__(self):
self.num =?10
def?print_num(self):
print(self.num +?10)
class?B(A):
def?my_func(self):
print("我自己B類的自定義方法")
b = B()
print(b.num)
b.print_num()
b.my_func()
"""
多繼承class D(C, A),如果多個父類C,A中都含有相同的方法和屬性print_num那么子類D繼承的是就是C的,注意繼承的先后順序
1- 父類中的屬性和方法如果相同的話,會繼承第一個父類的屬性和方法,按照集成的順序走init構造方法
2- D類中重寫父類的方法,如果自己d類中重寫了init方法,那么就不會繼承任何的父類屬性從init方法中
3- 換句話,子類重寫了父類的方法,那么不在使用父類同名的方法,包括init構造方法
4- 子類中重寫了父類的方法但是還是想調用父類的方法,
"""
class?C(object):
def?__init__(self):
self.num =?28
def?print_num(self):
print(self.num +?10)
class?D(C, A):
def?__init__(self):
self.age =?"這是D類自己的屬性age"
self.num =?"這是D類重寫父類的屬性num"
def?print_num(self):
self.__init__() ? ??# 再將self.num更改回來
print("這是D自己重寫父類的方法")
# 但是子類還是想使用**父類的屬性**調用父類重名的print_num方法
# 使用A.__init__(self)方法來更改self.num的值
def?print_a_num(self):
print(d.num) ? ? ? ?# 本來D對象中self.num = "這是D類重寫父類的屬性num"
A.__init__(self) ? ?# 把self傳進去,當前的self.num = 10
A.print_num(self)
# 或者使用super在子類方法中調用父類的方法
def?print_c_num(self):
# super(D, self).print_num() ? ?或者下面的簡寫形式
super().print_num()
def?my_func(self):
print("我自己D類的自定義方法")
d = D()
d.print_a_num()
print(d.num)
d.print_num()
"""
類中的私有屬性和方法
1- 父類中的money不想讓子類繼承,進行私有self.__屬性名
2- 方法前加上兩個下劃線使方法私有化, 私有的屬性和方法只能在類內使用
3- # 私有屬性子類不能使用,相當于java中的對象不能加點來獲取private的屬性值
"""
class?Master(object):
def?__init__(self):
self.kongfu =?"古法"
self.__money =?100000 ??# 兩個下劃線開頭表示私有屬性
def?make_cake(self):
print(self.__money) ? ??# 私有屬性可以在類自己種使用
print("制作古法煎餅果子")
def?__hello_python(self):
print("你好python")
lishifu = Master()
lishifu.make_cake()
print(lishifu.kongfu)
# print(lishifu.money)
"""
子類不能繼承父類的私有屬性和方法
因為根本沒有繼承下來,所以子類內部方法中根本就不能調用父類的私有屬性和方法
"""
class?Prentice(Master):
def?xx(self):
print("xx")
self.__hello_python()
damao = Prentice()
print(damao.kongfu)
damao.__hello_python
damao.xx()
Python
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。