裝飾器python
@ 裝飾器函數名linux
myfun = 裝飾器函數名(myfun)閉包
函數的文檔字符串
函數的文檔字符串由函數的 __doc__ 屬性綁定app
模塊
模塊的分類:
內建模塊 標準庫模塊 第三方模塊ide
用戶本身編寫的模塊函數
模塊的導入語句有三種:
import 語句
from import 語句
from import * 語句ui
dir() 函數 返回當前做用域內有哪兒些變量spa
內建模塊:
math sys time操作系統
decorators(專業提升篇)
函數名是變量,它綁定一個函數
函數名 / 函數名()的區別命令行
什麼是裝飾器
裝飾器是一個函數,主要做用是用來包裝另外一個函數或類(後面會講)
做用:
裝飾的目的是在不改變原函數名(或類名)的狀況下,改變被包裝對象的行爲
指裝飾器傳入的是一個函數, 返回的也是一個函數
語法:
def 裝飾器函數名(參數):
語句塊
return 函數對象
@裝飾器函數名1<換行>
@裝飾器函數名2<換行>
def 函數名(形參列表):
語句塊
例:
函數裝飾器的定義用調用
1 def mydeco(fn): 2 def fx(): 3 print("======這是myfunc調用前=======") 4 fn() 5 print('------這是myfunc調用後-------')#加fn()後, 閉包,def fx() 6 return fx 7 8 @mydeco#@等 9 def myfunc(): 10 print("myfunc被調用") 11 12 # myfunc = mydeco(myfunc)#@等#原理就是改變原來變量綁定的函數 13 14 15 myfunc() 16 myfunc() 17 myfunc()
1 tarena@tedu:~/python/20180717$ python3 mydeco.py 2 myfunc被調用 3 myfunc被調用 4 myfunc被調用 5 6 tarena@tedu:~/python/20180717$ python3 mydeco.py 7 ============= 8 ------------- 9 ============= 10 ------------- 11 ============= 12 ------------- 13 tarena@tedu:~/python/20180717$ python3 mydeco.py 14 ============= 15 ------------- 16 ============= 17 ------------- 18 ============= 19 ------------- 20 21 tarena@tedu:~/python/20180717$ python3 mydeco.py 22 ======這是myfunc調用前======= 23 myfunc被調用 24 ------這是myfunc調用後------- 25 ======這是myfunc調用前======= 26 myfunc被調用 27 ------這是myfunc調用後------- 28 ======這是myfunc調用前======= 29 myfunc被調用 30 ------這是myfunc調用後------- 31 32 tarena@tedu:~/python/20180717$ python3 mydeco.py 33 myfunc被調用 34 myfunc被調用 35 myfunc被調用
函數的文檔字符串
函數內第一次未被賦值給任何變量的字符串是次函數的文檔字符串
不會被解釋執行器忽略, 註釋會, 因此不是註釋是文檔字符串
語法:
def 函數名(參數列表):
’函數文檔字符串‘
函數語句塊
例:
def myfun(name, x):
'''這是函數的文檔字符串
name 表示人名
x 表示錢
'''
pass
>>> help(myfun)#查看
1 def myfunc(): 2 print("myfunc被調用") 3 4 myfunc = lambda: print("hello") 5 6 7 myfunc() 8 myfunc() 9 myfunc() 10 11 12 13 myfunc() 14 myfunc()
說明:
文檔字符串一般用來講明本函數的功能和使用方法
在交互模式下輸入:help(函數名)能夠查看函數的'文檔字符串'
函數的文檔字符串綁定在函數的__doc__屬性上
函數的 __doc__ 屬性
用於綁定函數的文檔字符串
__doc__ 屬性用於記錄文檔字符串
函數名.__doc__
函數的__name__ 屬性
__name__ 用於記錄函數的名稱 x.__name__
>>> def infos(name:'姓名', age:'年齡'=1, address:'家庭住址'='未填寫') -> None:
... '這是幫註文檔'
... pass
...
>>> help(infos)
[1]+ Stopped python3
函數定義語句(def 語句) 的完整語法:
[@裝飾器1]
[@裝飾器2]
[...]
def 函數名([位置形參], [*元組形參], [命名關鍵字形參])
'''文檔字符串'''
語句塊
注:[]表明其內部能夠省略
>>>help("def") # 有興趣的話能夠看看,我是拒絕的.
L=[1,2,3]
def f(n=0,lst=[]):
lst.append(n)
print(lst)
f(4,L) # 打印結果是什麼? [1,2,3,4]
f(5,L) # 打印結果是什麼? [1,2,3,4,5]
f(100) [100]
f(100) # 打印結果是什麼?爲何?[100,100]
f(200) [100,200]
交互退出exit()
裝飾器的應用場景及用法
銀行的存取款系統
1 # 一個函數被兩個裝飾器前後順序裝飾 2 def massage_send(fn): 3 def fy(name, x): 4 fn(name, x)#先辦理業務 5 print(name, "辦理了", x, '元的業務![工商銀行]') 6 return fy#閉包 7 8 9 10 def privileged_check(fn): 11 def fx(name, x):#形參調用規則一致 12 print("正在檢查權限... 經過") 13 fn(name, x)#調用被裝飾函數save_money和withdraw 14 return fx 15 16 @privileged_check 17 def save_money(name, x): 18 print(name, '存錢', x, '元') 19 20 @massage_send #先調用法送消息, 而後是權限, 最後是取錢 21 @privileged_check 22 def withdraw(name, x): 23 print(name, '取錢', x, '元') 24 25 save_money('小張', 200) 26 save_money('小楊', 500) 27 withdraw('小趙', 300) 28 withdraw('小洪', 1000) 29 30 # 運行結果顯示,存在對比,細看 31 # 正在檢查權限... 經過 32 # 小張 存錢 200 元 33 # 正在檢查權限... 經過 34 # 小楊 存錢 500 元 35 # 正在檢查權限... 經過 36 # 小趙 取錢 300 元 37 # 小趙 辦理了 300 元的業務![工商銀行] 38 # 正在檢查權限... 經過 39 # 小洪 取錢 1000 元 40 # 小洪 辦理了 1000 元的業務![工商銀行]
模塊是一個包含有一系列數據、函數、類等組成的程序組
模塊是一個文件, 模塊文件名一般以.py結尾
做用:
讓一些相關 的數據, 函數,類等有邏輯的組織在一塊兒, 使邏輯結構更加清晰
模塊中的數據, 函數, 類等可提供給其餘模塊或程序使用
模塊的分類:
1.內置模塊(builtins)在解析器的內部能夠直接使用(一般用C語言寫的)
2.標準庫模塊,安裝python時已安裝且能夠直接使用
3.第三方模塊(一般爲開源),須要本身安裝
4.用戶本身編定的模塊(能夠做爲其餘人的第三方模塊)
import 語句
語法:
import 模塊名1 [as 模塊新名1], 模塊名2 [as 模塊新名2], .....
例:
import math #導入math模塊
import sys, os
import copy
import sys
做用:
將一個(某)模塊總體導入到當前模塊中
屬性用法:
模塊名.屬性名
或
模塊名.函數屬性名(實參)
如:
math.factorial(5)
例:
math.factorial(5)#階乘120
dir(odj)函數返回全部屬性的字符串列表
help(obj)函數能夠查看模塊的相關文檔字符串
練習:
1.輸入一個圓的半徑, 打印出這個圓的面積
2.輸入元的面積, 打印出這個圓的半徑
(要求用math模塊內的函數和變量
>>> import math as m, sys as s, os as o
1 import math 2 r = float(input("請輸入圓的半徑:"))#float浮點數 3 area = (math.pi)*r**2 4 print("圓面積", area) 5 6 7 import math as m 8 area = float(input("請輸入圓面積:")) 9 r = m.sqrt(area/m.pi) 10 print("圓半徑", r) 11 12 import math 13 r = float(input("請輸入圓的半徑:")) 14 z = 2*(math.pi)*r 15 print('圓周長', z)
語法:
form 模塊名 import 模塊屬性名1[as 屬性新名1], 模塊屬性名2 [as 屬性新名2], ...
@從.. @導入
例:
import math as m,sys as s ...
做用:
將某模塊的一個或多個屬性導入到當前模塊的做用域
示例:
from math import pi
from math import sin
from math import factorial as fac
python官方建議首選 import 語句(總體導入)
再次 from import 語句
最後 from import * 語句(可能致使變量名衝突)
語法:
from 模塊名 import *
做用:
將某模塊的全部屬性導入到當前的模塊
例:
from math import *
print(sin(pi/2))
print(factorial)
dir 函數
dir([對象]) 返回一個字符串的列表(變量名)
說明:
若是沒有給參數調用, 則返回當前做用域內的全部變量的列表, 若是給定一個對象做爲參數, 則返回這個對象的全部變量的列表
1)對於一個模塊,返回這個模塊的所有屬性
2)對於一個類對象,返回這個類的全部變量,並遞歸基類對象的全部變量
3)對於其餘對象,返回全部變量,類變量和基類變量
例:
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
>>> pi = '派克筆'
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'pi']
>>> a = 100
>>> b = 200
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'b', 'pi']
>>> import math#在本地創建模塊
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'b', 'math', 'pi']
>>> from math import sin, cos, sqrt
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'b', 'cos', 'math', 'pi', 'sin', 'sqrt']
>>> sqrt(100)
10.0
>>> from math import *
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'b', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'math', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']
1 phone_number = input(''1386-666-0006'') 2 hiding_number = phone_number.replace(phone_number[:9],'*' * 9)#replace字符串替換 3 print(hiding_number)
1 print('{} a word she can get what she {} for.'.format('With','came')) 2 print('{preposition} a word she can get what she {verb} for'.format(preposition = 'With',verb = 'came')) 3 print('{0} a word she can get what she {1} for.'.format('With','came'))
數學模塊用法:
import math
# 或
from math import *
變量 描述
math.e 天然對數的底e
math.pi 圓周率pi
函數名 描述
math.ceil(x) 對x向上取整,好比x=1.2,返回2
math.floor(x) 對x向下取整,好比x=1.2,返回1
math.sqrt(x) 返回x的平方根
math.factorial(x) 求x的階乘
math.log(x[, base]) 返回以base爲底x的對數, 若是不給出base,則以天然對數e爲底
math.log10(x) 求以10爲底x的對數
math.pow(x, y) 返回 x**y (x的y次方)
math.fabs(x) 返回浮點數x的絕對值
角度和弧度degrees互換
math.degree(x) 將弧度x轉換爲角度
math.radians(x) 將角度x轉換爲弧度
三角函數
math.sin(x) 返回x的正弦(x爲弧度)
math.cos(x) 返回x的餘弦(x爲弧度)
math.tan(x) 返回x的正切(x爲弧度)
math.asin(x) 返回x的反正弦(返回值爲爲弧度)
math.acos(x) 返回x的反餘弦(返回值爲爲弧度)
math.atan(x) 返回x的反正切(返回值爲爲弧度)
>>> log(25,5)
2.0
>>> log(8, 2)
3.0
>>> log(2.71828)
0.999999327347282
模塊名 time
詳見
時間模塊 time
此模塊提供了時間相關的函數,且一直可用
時間簡介
公元紀年是從公元 0000年1月1日0時開始的
計算機元年是從1970年1月1日0時開始的,此時時間爲0,以後每過一秒時間+1
UTC 時間 (Coordinated Universal Time) 是從Greenwich時間開始計算的.
UTC 時間不會因時區問題而產生錯誤
DST 陽光節約時間(Daylight Saving Time),又稱夏令時, 是一個通過日照時間修正後的時間
時間元組
時間元組是一個9個整型元素組成的,這九個元素自前至後依次爲:
四位的年(如: 1993)
月 (1-12)
日 (1-31)
時 (0-23)
分 (0-59)
秒 (0-59)
星期幾 (0-6, 週一是 0)
元旦開始日 (1-366)
夏令時修正時間 (-1, 0 or 1).
注:
若是年份值小於100,則會自動轉換爲加上1900後的值
模塊名: time
時間模塊用法:
import time
# 或
from time import xxx
# 或
from time import *
變量 描述
time.altzone 夏令時時間與UTC時間差(秒爲單位)
time.daylight 夏令時校訂時間
time.timezone 本地區時間與UTC時間差(秒爲單位)
time.tzname 時區名字的元組, 第一個名字爲未經夏令時修正的時區名,
第一個名字爲經夏令時修正後的時區名
注: CST爲中國標準時間(China Standard Time UTC+8:00)
函數名 描述
time.time() 返回從計算機元年至當前時間的秒數的浮點數(UTC時間爲準)
time.sleep(secs) 讓程序按給定秒數的浮點數睡眠一段時間
time.gmtime([secs]) 用給定秒數轉換爲用UTC表達的時間元組
(缺省返回當前時間元組)
time.asctime([tuple]) 將時間元組轉換爲日期時間字符串
time.mktime(tuple) 將本地日期時間元組轉換爲新紀元秒數時間(UTC爲準)
time.localtime([secs]) 將UTC秒數時間轉換爲日期元組(以本地時間爲準)
import time
print("hello")
time.sleep(10)
print("world")
寫一個程序, 輸入你的出生日期
1.算出你已經出生多少天
2.算出你的出生那天是星期幾
1 a = int(input("請輸入你的生日年:")) 2 b = int(input("請輸入你的生日月:")) 3 c = int(input("請輸入你的生日日:")) 4 import time 5 s = time.time()#UTC 6 h = time.mktime((a, b, c, 0, 0, 0, 0, 0, 0))#UTC 7 print(h) 8 t = (s -h)/(3600*24)#天數 9 print(t) 10 w = time.localtime(s - h) 11 print(w) 12 13 14 import time 15 16 year = int(input("請輸入你的生日年:")) 17 month = int(input("請輸入你的生日月:")) 18 day = int(input("請輸入你的生日日:")) 19 20 tuple_birth = (year, month, day, 0, 0, 0, 0, 0, 0) 21 22 birth_second = time.mktime(tuple_birth)#獲得出生時計算機內部的秒數 23 24 second = time.time() - birth_second 25 #你一共活了多少秒 26 27 print("您已經出生", second/60/60//24, '天') 28 29 t = time.localtime(birth_second)#元組 30 print(t) 31 weeks ={0:"星期一", 1:"星期二", 2:"星期三", 3:"星期四", 4:"星期五", 5:"星期六", 6:"星期日"} 32 33 print("您的出生那天是:",weeks[t[6]])
運行時系統相關的信息
sys模塊的屬性
屬性 描述
sys.path 模塊搜索路徑 path[0] 是當前腳本程序的路徑名,不然爲 ''
sys.modules 已加載模塊的字典
sys.version 版本信息字符串
sys.version_info 版本信息的命名元組
sys.platform 操做系統平臺名稱信息
sys.argv 命令行參數 argv[0] 表明當前腳本程序路徑名
sys.copyright 得到Python版權相關的信息
sys.builtin_module_names 得到Python內建模塊的名稱(字符串元組)
sys模塊的函數
函數名 描述
sys.exit([arg]) 退出程序,正常退出時sys.exit(0)
sys.getrecursionlimit() 獲得遞歸嵌套層次限制(棧的深度)
sys.setrecursionlimit(n) 獲得和修改遞歸嵌套層次限制(棧的深度)
1 import sys 2 print("curversion_is", sys.version, sys.version_info) 3 # print(sys.modules) 4 sys.version_info>(2.7) 5 >>> import sys 6 >>> sys.platform 7 'linux'
計算輸入的參數個數
1 import sys 2 print("當前您輸入了", len(sys.argv), '個參數') 3 print("這些參數是", sys.argv)#用戶敲命令的時候輸入的 4 5 6 tarena@tedu:~/python/20180717$ python3 mydeco.py 7 當前您輸入了 1 個參數 8 這些參數是 ['mydeco.py'] 9 tarena@tedu:~/python/20180717$ python3 mydeco.py -l/home/tarena 10 當前您輸入了 2 個參數 11 這些參數是 ['mydeco.py', '-l/home/tarena']
1 import sys 2 print("hello") 3 sys.exit(0) 4 print("world")
練習:
1.精編寫函數fun, 其功能是計算下列多項式的和:
fn = 1 + 1/1! + 1/2! + 1/3! + 1/4! + .. + 1/n!
(建議用數學模型的factorial實現)
求當n 等於100時,fn的值
看一下fn(100)的值是什麼
1 # 循環 2 import math 3 def fun(n): 4 s = 0 5 for i in range(0, n+1): 6 s += 1/math.factorial(i) 7 return s 8 9 print(fun(100)) 10 # 遞歸 11 import math 12 def fun(n): 13 if n == 0: 14 return 1 15 return 1/math.factorial(n)+fun(n-1) 16 17 print(fun(100)
2.寫一個程序,以電子時鐘格式:
HH:MM:SS格式顯示時間
要求每隔一秒變化一次
1 import time 2 def run(): 3 while True: 4 t = time.localtime() 5 # print("%02d:%02d:%02d" % (t[3], t[4], t[5]), end='\r') 6 print("%02d:%02d:%02d" % t[3:6], end='\r') 7 time.sleep(1) 8 run()
1 import os 2 import time 3 def run(): 4 while True: 5 t = time.localtime() 6 # print("%02d:%02d:%02d" % (t[3], t[4], t[5]), end='\r') 7 print('+-----------------+') 8 print("%02d:%02d:%02d" % (t[3:6]), end='\r') 9 os.system('clear') 10 print('+-----------------+') 11 time.sleep(1) 12 13 print('Jack牌時鐘') 14 run() 15 16 from time import* 17 import os 18 def clock(): 19 while True: 20 now_time=localtime() 21 t_clock=now_time[3:6] 22 os.system('clear') 23 time='%d時%d分%d秒'%t_clock 24 print('Alan牌時鐘') 25 print('+-------------+') 26 print('|'+time.center(10)+'|') 27 print('+-------------+') 28 sleep(1) 29 clock()
3.寫函數f(n)求下多項式的和
fn = 1/1 - 1/3 +1/5 -1/7 +1/9 ....1/(2*n-1)的和
求當n 取值爲1000000
1)打印 f(1000000) 的值
2)打印 f(1000000)*4 的值,看看是什麼
1 def f(n): 2 s = 0 3 sign = 1#符號(正負) 4 for i in range(1, n+1): 5 s += sign * 1 /(2*i-1)#(-1)**(i+1) / (2 * x - 1) 6 sign *= -1 7 8 return s
裝飾器爲何必定是閉包函數???