函數定義時的幾類常見參數:
看如下代碼
def stu_register(name,age,country,course):
print("----注冊學⽣生信息------")
print("姓名:",name)
print("age:",age)
print("國籍:",country)
print("課程:",course)
stu_register("王⼭山炮",22,"CN","python_devops")
stu_register("張叫春",21,"CN","linux")
stu_register("劉⽼老老根",25,"CN","linux")
發現 country 這個參數 基本都 是”CN”, 就像我們在⽹網站上注冊⽤用戶,像國籍這種信息,你不不填寫,默認 就會是 中國, 這就是通過默認參數實現的,把country變成默認參數⾮非常簡單
def stu_register(name,age,course,country="CN"):
這樣,這個參數在調⽤用時不不指定,那默認就是CN,指定了了的話,就⽤用你指定的值。
另外,你可能注意到了了,在把country變成默認參數後,我同時把它的位置移到了了最後⾯面,為什麼 呢?
這是語法強制的,默認參數放在其他參數後邊,為啥呢? 假設允許這樣:
def stu_register(name,age,country="CN",course):
那調⽤用時
stu_register("Mack",22,"Python","US")
你告訴我,第3個參數 python 到底應該給到country還是course呢? ⽆無論給哪個,都會出現歧義,所以 Python語法⼲干脆就讓你把默認參數放最後, 解釋器在處理理函數時參數時,按優先級,位置參數>默認參數
。
正常情況下,給函數傳參數要按順序,不不想按順序就可以⽤用關鍵參數,只需指定參數名即可(指定了了參數 名的參數就叫關鍵參數),但記住⼀一個要求就是, 關鍵參數
必須放在位置參數
(以位置順序確定對應關系的參數)之後。
def stu_register(name, age, course='PY' ,country='CN'):
print("----注冊學⽣生信息------")
print("姓名:", name)
print("age:", age)
print("國籍:", country)
print("課程:", course)
調⽤用可以這樣( 正確的調用方式: )
stu_register("王⼭山炮",course='PY', age=22,country='JP' )
但絕不可以這樣
stu_register("王⼭山炮",course='PY',22,country='JP' )
當然這樣也不⾏
stu_register("王⼭山炮",22,age=25,country='JP' )
這樣相當於給age賦值2次,會報錯!
注意,參數優先級順序是 位置參數>關鍵參數
若你的函數在定義時不不確定⽤用戶想傳⼊入多少個參數,就可以使⽤用⾮固定參數
def stu_register(name,age,*args): # *args 會把多傳⼊入的參數變成⼀一個元組形式
print(name,age,args)
stu_register("Alex",22)
#輸出
#Alex 22 () #後⾯面這個()就是args,只是因為沒傳值,所以為空
stu_register("Jack",32,"CN","Python") #輸出
# Jack 32 ('CN', 'Python')
還可以有⼀個 **kwargs
def stu_register(name,age,*args,**kwargs): # *kwargs 會把多傳⼊入的參數變成⼀一個dict形 式
print(name,age,args,kwargs)
stu_register("Alex",22)
#輸出
#Alex 22 () {}#後⾯面這個{}就是kwargs,只是因為沒傳值,所以為空
stu_register("Jack",32,"CN","Python",sex="Male",province="ShanDong") #輸出
# Jack 32 ('CN', 'Python') {'province': 'ShanDong', 'sex': 'Male'}
看如下代碼
name = "Alex Li" def change_name():
name = "金⻆大王, ⼀個有Tesla的高級屌絲" print("after change", name)
change_name() print("在外面看name改了了麼?",name)
# 輸出
>>>
after change ⾦⻆大王,⼀個有Tesla的高級屌絲 在外⾯看name改了了麼? Alex Li
為什麼在函數內部改了name的值後, 在外面print的時候卻沒有改呢? 因為這兩個name根本不是⼀回事
變量的查找順序是局部變量>全局變量
;就是想在函數⾥裡裡修改全局變量量怎麼辦?
name = "Alex Li"
def change_name():
global name #聲明⼀一個全局變量量
name = "Alex ⼜又名⾦金金⻆角⼤大王,愛⽣生活、愛⾃自由、愛姑娘"
print("after change",name)
change_name()
print("在外⾯面看看name改了了麼?", name)
global name 的作⽤就是要在函數⾥聲明全局變量name ,意味著最上⾯的 name = “Alex Li” 即使不寫,程序最後面的print也可以打印name。雖然可以改,但不不建議⽤這個global語法,隨著代碼增多 ,會造成代碼調試困難。
每個函數的作⽤用我都幫你標好了了
1. abs # 求絕對值
2. all #Return True if bool(x) is True for all values x in the iterable.If the iterable is empty, return
True.
3. any #Return True if bool(x) is True for any x in the iterable.If the iterable is empty, return
False.
4. ascii #Return an ASCII-only representation of an object,ascii(“中國”) 返回”‘\u4e2d\u56fd’”
5. bin #返回整數的2進制格式
6. bool # 判斷⼀一個數據結構是True or False, bool({}) 返回就是False, 因為是空dict
7. bytearray # 把byte變成 bytearray, 可修改的數組
8. bytes # bytes(“中國”,”gbk”)
9. callable # 判斷⼀一個對象是否可調⽤用
10. chr # 返回⼀一個數字對應的ascii字符 , ⽐比如chr(90)返回ascii⾥裡裡的’Z’
11. classmethod #⾯面向對象時⽤用,現在忽略略
12. compile #py解釋器器⾃自⼰己⽤用的東⻄西,忽略略
13. complex #求復數,⼀一般⼈人⽤用不不到
14. copyright #沒⽤用
15. credits #沒⽤用
16. delattr #⾯面向對象時⽤用,現在忽略略
17. dict #⽣生成⼀一個空dict
18. dir #返回對象的可調⽤用屬性
19. divmod #返回除法的商和余數 ,⽐比如divmod(4,2),結果(2, 0)
20. enumerate #返回列列表的索引和元素,⽐比如 d = [“alex”,”jack”],enumerate(d)後,得到(0, ‘alex’)
(1, ‘jack’)
21. eval #可以把字符串串形式的list,dict,set,tuple,再轉換成其原有的數據類型。
22. exec #把字符串串格式的代碼,進⾏行行解義並執⾏行行,⽐比如exec(“print(‘hellworld’)”),會解義⾥裡裡⾯面的字符
串串並執⾏行行
23. exit #退出程序
24. filter #對list、dict、set、tuple等可迭代對象進⾏行行過濾, filter(lambda x:x>10,
[0,1,23,3,4,4,5,6,67,7])過濾出所有⼤大於10的值
25. float #轉成浮點
26. format #沒⽤用
27. frozenset #把⼀一個集合變成不不可修改的
28. getattr #⾯面向對象時⽤用,現在忽略略
29. globals #打印全局作⽤用域⾥裡裡的值
30. hasattr #⾯面向對象時⽤用,現在忽略略
31. hash #hash函數
32. help
33. hex #返回⼀一個10進制的16進制表示形式,hex(10) 返回’0xa’
34. id #查看對象內存地址
35. input
36. int
37. isinstance #判斷⼀一個數據結構的類型,⽐比如判斷a是不不是fronzenset, isinstance(a,frozenset) 返
回 True or False
38. issubclass #⾯面向對象時⽤用,現在忽略略
39. iter #把⼀一個數據結構變成迭代器器,講了了迭代器器就明⽩白了了
40. len
41. list
42. locals
43. map # map(lambda x:x**2,[1,2,3,43,45,5,6,]) 輸出 [1, 4, 9, 1849, 2025, 25, 36]
44. max # 求最⼤大值
45. memoryview # ⼀一般⼈人不不⽤用,忽略略
46. min # 求最⼩小值
47. next # ⽣生成器器會⽤用到,現在忽略略
48. object #⾯面向對象時⽤用,現在忽略略
49. oct # 返回10進制數的8進制表示
50. open
51. ord # 返回ascii的字符對應的10進制數 ord(‘a’) 返回97,
52. print
53. property #⾯面向對象時⽤用,現在忽略略
54. quit
55. range
56. repr #沒什什麼⽤用
57. reversed # 可以把⼀一個列列表反轉
58. round #可以把⼩小數4捨5⼊入成整數 ,round(10.15,1) 得10.2
59. set
60. setattr #⾯面向對象時⽤用,現在忽略略
61. slice # 沒⽤用
62. sorted
63. staticmethod #⾯面向對象時⽤用,現在忽略略
64. str
65. sum #求和,a=[1, 4, 9, 1849, 2025, 25, 36],sum(a) 得3949
66. super #⾯面向對象時⽤用,現在忽略略
67. tuple
68. type
69. vars #返回⼀一個對象的屬性,⾯面向對象時就明⽩白了了
70. zip #可以把2個或多個列列表拼成⼀一個, a=[1, 4, 9, 1849, 2025, 25, 36],b = [“a”,”b”,”c”,”d”],
list(zip(a,b)) #得結果 [(1, 'a'), (4, 'b'), (9, 'c'), (1849, 'd')]
導入模塊有以下幾種⽅方式:
import module_a #導⼊
from module import xx # 導入某個模塊下的某個⽅法 or ⼦模塊
from module.xx.xx import xx as rename #導⼊後⼀個⽅法後重命令
from module.xx.xx import * #導⼊⼀個模塊下的所有⽅法,不建議使⽤
module_a.xxx #調⽤
注意:模塊⼀旦被調⽤,即相當於執⾏了另外⼀個py⽂文件⾥的代碼
。
這個最簡單, 創建⼀個.py⽂文件,就可以稱之為模塊,就可以在另外一個程序⾥導⼊。
有沒有發現,⾃⼰寫的模塊只能在當前路徑下的程序裡才能導⼊,換一個目錄再導⼊自己的模塊就報錯。說找不到了, 這是為什麼? 這與導⼊模塊的查找路徑有關。
import sys
print(sys.path)
輸出(注意不不同的電腦可能輸出的不不太⼀一樣)
['', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python36.zip', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site- packages']
你導入⼀個模塊時,Python解釋器會按照上⾯列表順序去依次到每個⽬錄下去匹配你要導⼊的模塊名, 只要在⼀個⽬目錄下匹配到了了該模塊名,就⽴刻導⼊入,不再繼續往後找。
注意列表第⼀個元素為空,即代表當前⽬錄,所以你⾃己定義的模塊在當前目錄會被優先導⼊入。
我們自⼰創建的模塊若想在任何地⽅都能調用,那就得確保你的模塊⽂件⾄少在模塊路徑的查找列表中。
我們⼀般把自⼰寫的模塊放在⼀個帶有“site-packages”字樣的⽬錄⾥,我們從⽹上下載安裝的各種第三方的模塊⼀般都放在這個⽬錄。
那如何從這個平台上下載代碼呢?
編譯源碼
python setup.py build 安裝源碼
python setup.py install
pip3 install paramiko #paramiko 是模塊名
# pip命令會⾃自動下載模塊包並完成安裝。
軟件⼀一般會被⾃自動安裝你python安裝⽬目錄的這個⼦子⽬目錄⾥裡裡
/your_python_install_path/3.6/lib/python3.6/site-packages
pip命令默認會連接在國外的python官⽅方服務器器下載,速度⽐比較慢,你還可以使⽤用國內的⾖豆瓣源,數據 會定期同步國外官⽹網,速度快好多。
pip install -i http://pypi.douban.com/simple/ alex_sayhi --trusted-host pypi.douban.com #alex_sayhi是模塊名
-i
後⾯跟的是⾖瓣源地址;—trusted-host
得加上,是通過網站https安全驗證⽤的。若你寫的項⽬較復雜,有很多代碼⽂件的話,為了方便便管理,可以⽤包來管理。 ⼀個包其實就是⼀個⽂件⽬錄,你可以把屬於同一個業務線的代碼⽂件都放在同一個包⾥。
如何創建⼀一個包?
只需要在目錄下創建⼀個空的 __init__.py ⽂件
, 這個目錄就變成了包。這個⽂件叫包的初始化⽂件 ,一般為空,當然也可以寫東西,當你調⽤這個包下及其任意⼦包的的任意模塊時, 這個 __init__.py ⽂件
都會先執⾏。
以下 有a、b 2個包,a2是a的⼦包,b2是b的⼦包。
若在a_module.py模塊⾥導⼊b2_mod.py的話,怎麼辦?
a_module.py的⽂件路徑為
/Users/alex/Documents/work/PyProjects/py8days_camp/day6/課件/a/a2/a_module.py
想導入成功,直接寫以下代碼就可以( 正確調用方式)
from day6.課件.b.b2 import b2_mod
為何從day6開始?⽽不是從 py8days_camp 或 課件 開始呢?
因為你的sys.path列列表裡,已經添加了相關的路徑
['/Users/alex/Documents/work/PyProjects/py8days_camp/day6/課件/a/a2', '/Users/alex/Documents/work/PyProjects/py8days_camp', # <---就是這個。。
'/Applications/PyCharm.app/Contents/helpers/pycharm_display',
'/Library/Frameworks/Python.framework/Versions/3.6/lib/python36.zip',
'/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6',
'/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload',
'/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site- packages',
'/Applications/PyCharm.app/Contents/helpers/pycharm_matplotlib_backend']
手動添加sys.path路徑
你會說,我沒有添加這個 ‘/Users/alex/Documents/work/PyProjects/py8days_camp’ 呀,它是怎
麼進到 sys.path 裡的?
答案是Pycharm自動幫你添加的,若你脫離pycharm再執⾏這個 a_module.py 就會報錯了。
Alexs-MacBook-Pro:a2 alex$ python3 a_module.py Traceback (most recent call last):
File "a_module.py", line 7, in <module> from day6.課件.b.b2 import b2_mod
ModuleNotFoundError: No module named 'day6'
不⽤用慌, ⾃己手動添加sys.path路徑就可以。
手動添加sys.path路徑的實現方式:
import os
import sys
base_dir=os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.pa th.dirname(os.path.abspath(__file__)))))) # 取到路路 徑/Users/alex/Documents/work/PyProjects/py8days_camp
print(base_dir)
sys.path.append(base_dir) # 添加到sys.path⾥裡裡
from day6.課件.b.b2 import b2_mod
os 模塊
提供了很多允許你的程序與操作系統直接交互的功能。
import os
得到當前工作⽬錄,即當前Python腳本工作的⽬錄路徑: os.getcwd()
返回指定⽬錄下的所有⽂件和⽬錄名:os.listdir()
函數用來刪除⼀個文件:os.remove()
刪除多個目錄:os.removedirs(r“c:\python”)
檢驗給出的路徑是否是⼀個⽂件:os.path.isfile()
檢驗給出的路徑是否是一個⽬錄:os.path.isdir()
判斷是否是絕對路路徑:os.path.isabs()
檢驗給出的路徑是否真地存:os.path.exists()
返回⼀個路徑的⽬錄名和文件名:os.path.split() e.g
os.path.split('/home/swaroop/byte/code/poem.txt') 結果: ('/home/swaroop/byte/code', 'poem.txt')
分離擴展名:os.path.splitext() 結果:('/usr/local/test', '.py')
e.g os.path.splitext('/usr/local/test.py')
獲取路徑名:os.path.dirname()
獲得絕對路徑: os.path.abspath()
獲取⽂件名:os.path.basename()
運⾏shell命令: os.system()
讀取操作系統環境變量HOME的值:os.getenv("HOME")
返回操作系統所有的環境變量: os.environ
設置系統環境變量,僅程序運⾏行行時有效:os.environ.setdefault('HOME','/home/alex')
給出當前平台使⽤的⾏終止符:os.linesep Windows使用'\r\n',Linux and MAC使用'\n'
指示你正在使用的平台:os.name 對於Windows,它是'nt',⽽對於Linux/Unix⽤用戶,它是'posix'
重命名:os.rename(old, new)
創建多級⽬錄:os.makedirs(r“c:\python\test”)
創建單個⽬錄:os.mkdir(“test”)
獲取文件屬性:os.stat(file) 修改文件權限與時間戳:os.chmod(file)
獲取文件⼤小:os.path.getsize(filename)
結合⽬目錄名與⽂文件名:os.path.join(dir,filename)
改變⼯工作⽬目錄到dirname: os.chdir(dirname)
獲取當前終端的⼤大⼩小: os.get_terminal_size()
殺死進程: os.kill(10884,signal.SIGKILL)
2.2 time 模塊 在平常的代碼中,我們常常需要與時間打交道。在Python中,與時間處理理有關的模塊就包括:time,datetime, calendar(很少用,不講),下⾯分別來介紹。
我們寫程序時對間的處理可以歸為以下3種:
在Python中,通常有這⼏種⽅式來表示