Python標準內建函式(11-15)
1.11 函式classmethod()
在Python程式中,函式classmethod()的功能是將函式包裝成類方法。其語法格式如下所示:
classmethod(function)
在Python程式中,經常使用@classmethod修飾符的用法。在宣告一個類方法時,通常使用如下所示的用法:
class C:
@classmethod
def f(cls, arg1, arg2, ...): ...
修飾符@classmethod對應的函式不需要例項化,不需要 self 引數,但第一個引數需要是表示自身類的 cls 引數,可以來呼叫類的屬性,類的方法,例項化物件等。@classmethod形式的用法是一個函式裝飾器,用於檢視函式定義中關於函式定義的詳細說明。@classmethod既可以在類上呼叫(如C.f()),也可以在例項上呼叫(如C().f())。除了例項的類,例項本身被忽略。如果一個類方法在子類上呼叫,那麼子類物件被傳遞為隱式的第一個引數。類方法不同於C++或Java中的靜態方法,如果需要靜態方法,請參考本章後面介紹的staticmethod()函式。
在下面的例項檔案xiu.py中,演示了使用@classmethod修飾符的過程。
class A(object): bar = 1 def func1(self): print('foo') @classmethod def func2(cls): print('func2') print(cls.bar) cls().func1() # 呼叫 foo 方法 A.func2() # 不需要例項化
執行後會輸出:
func2
1
foo
在下面的例項檔案xiu1.py中,演示了使用修飾符@classmethod修飾指定方法的過程。
class C: @classmethod def f(cls, arg1): print(cls) print(arg1) C.f('類物件呼叫類方法') c = C() c.f('類例項物件呼叫類方法')
執行後會輸出:
<class '__main__.C'>
類物件呼叫類方法
<class '__main__.C'>
類例項物件呼叫類方法
在類中使用修飾符@classmethod後,當類被繼承後,子類也可以呼叫父類的類方法,但是第一個引數傳入的是子類的類物件。例如下面的例項檔案xiu2.py演示了這一用法。
class C:
@classmethod
def f(cls, arg1):
print(cls)
print(arg1)
class D(C):
pass
D.f("子類的類物件呼叫父類的類方法")
執行後會輸出:
<class '__main__.D'>
子類的類物件呼叫父類的類方法
1.12 函式compile()
在Python程式中,函式compile()的功能是將一個字串編譯為位元組程式碼。使用函式compile()的語法格式如下所示。
compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1)
- source:字串或者AST(Abstract Syntax Trees)物件,函式compile()能夠將source編譯成程式碼物件,或者AST(Abstract Syntax Tree,抽象語法樹)物件。程式碼物件可以由exec()或eval()執行。源可以是普通字串,位元組字串或AST物件。
- filename:程式碼檔名稱,如果不是從檔案讀取程式碼則傳遞一些可辨認的值;
- mode:指定編譯程式碼的模式,可以指定為 exec、eval、single。如果source由語句序列組成,則它可以是'exec';如果它是單個語句,則可以使用'eval';如果它由單個互動式語句組成,則可以使用'single'。
- flags:變數作用域,區域性名稱空間,如果被提供,可以是任何對映物件;
- flags和dont_inherit:是用來控制編譯原始碼時的標誌。
- optimize:指定編譯器的優化級別;預設值-1選擇由-O選項給出的直譯器的優化級別。顯式級別為0(無優化; __debug__為真),1(宣告被刪除,__debug__為假 )或2(docstrings也被刪除)。
在上述引數中,可選引數flags和dont_inherit控制哪些未來版本的語句會應用於源編譯。如果兩者都不存在(或兩者都為零),則使用在呼叫compile()的程式碼中生效的未來語句來編譯程式碼。如果給出了flags引數且沒有給出dont_inherit引數(或者為0),除了本該使用的future語句之外,由flags引數指明的future語句也會影響編譯。如果dont_inherit是非0整數,flags引數被忽略(呼叫compile周圍的有效的future語句被忽略)。
在下面的例項檔案com.py中,演示了使用函式compile()編譯字串的過程。
str = "for i in range(0,10): print(i)"
c = compile(str,'','exec') # 編譯為位元組程式碼物件
print(c)
print(exec(c))
str = "3 * 4 + 5"
a = compile(str,'','eval')
print(eval(a))
在上述程式碼中分別使用了函式compile()的exec和eval兩種編譯型別,執行後會輸出:
<code object <module> at 0x0000026B6382EA50, file "", line 1>
0
1
2
3
4
5
6
7
8
9
None
17
在下面的例項檔案comp.py中,演示了在互動語句中使用single的過程。
#流程語句使用exec
code1 = 'for i in range(0,10): print (i)'
compile1 = compile(code1,'','exec')
print(exec (compile1))
#簡單求值表示式用eval
code2 = '1 + 2 + 3 + 4'
compile2 = compile(code2,'','eval')
print(eval(compile2))
#互動語句用single
code3 = 'name = input("please input your name:")'
compile3 = compile(code3,'','single')
①print(exec(compile3)) #執行時顯示互動命令,提示輸入
②print(name) #執行後name變數有值
執行後會輸出:
0
1
2
3
4
5
6
7
8
9
None
10
please input your name:py
None
py
在上述程式碼中,當執行到①時會顯示一個互動命令語句,提示我們輸入一個變數值,這樣變數name便會有一個值,執行②程式碼時不會出錯。如果在執行②前變數name的值不存在,則會出現執行錯誤,例如下面程式碼的執行過程:
>>> #互動語句用single
>>> code3 = 'name = input("please input your name:")'
>>> compile3 = compile(code3,'','single')
>>> name #執行前name變數不存在
Traceback (most recent call last):
File "<pyshell#29>", line 1, in <module>
name
NameError: name 'name' is not defined
1.13 函式complex()
在Python程式中,函式complex()的功能是建立一個值為“real + imag * j”的複數或者轉化一個字串或數為複數。如果第一個引數為字串,則不需要指定第二個引數。使用函式complex()的語法格式如下所示。
class complex([real[, imag]])
real:int、long、float或字串;
imag:int、long或float型別。
函式complex()的返回值形式為“real + imag * j”的複數,或將字串或數字轉換為複數。如果第一個引數是一個字串,它將被解釋成複數,同時函式不能有第二個引數。第二個引數不能是字串。每個引數必須是數值型別(包括複數)。如果省略引數imag,則預設為零,建構函式會像int和float一樣進行轉換。如果省略這兩個引數,則返回0j。
在下面的例項檔案compl.py中,演示了使用函式complex()建立複數的過程。
print(complex()) #當兩個引數都不提供時,返回複數 0j。
print(complex(1, 2))
print(complex(1)) # 數字
print(complex("1")) # 當做字串處理
# 注意:下面的程式碼在"+"號兩邊不能有空格,也就是不能寫成"1 + 2j",應該是"1+2j",否則會報錯
print(complex("1+2j"))
print(complex(2)) #當第一個引數為int或者float時,第二個引數可為空,表示虛部為0
print((2+0j)) #如果提供第二個引數,第二個引數也需為int或者float。
執行後會輸出:
0j
(1+2j)
(1+0j)
(1+0j)
(1+2j)
(2+0j)
(2+0j)
在Python程式中,當函式complex()中的第一個引數為字串時,在呼叫時不能提供第二個引數。此時的字串引數,需要是一個能表示複數的字串,而且加號或者減號左右不能出現空格。例如在下面的程式碼中,函式complex()的第一個引數為字串,不能接受第二個引數。接受第二個引數時會出錯。
>>> complex('1+2j',2) #第一個引數為字串,不能接受第二個引數,
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
complex('1+2j',2)
TypeError: complex() can't take second arg if first is a string
在函式complex()中的"+"號兩邊不能有空格,否則也會出現編譯錯誤,例如下面的程式碼。
>>> complex('1 + 2j') #不能有空格
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
complex('1 + 2j')
ValueError: complex() arg is a malformed string
1.14 函式delattr()
在Python程式中,函式delattr()的功能是刪除指定物件的某個屬性。使用函式delattr()的語法格式如下所示。
delattr(object, name)
- object:物件;
- name:是一個字串,這個字串必須是物件的某個屬性的名字。
例如程式碼“delattr(x, 'foobar')”等同於“del x.foobar”,表示刪除物件x中的屬性foobar。在下面的例項檔案del.py中,演示了使用函式delattr()刪除指定屬性的過程。
class Coordinate:
x = 10
y = -5
z = 0
point1 = Coordinate()
print('x = ', point1.x)
print('y = ', point1.y)
print('z = ', point1.z)
delattr(Coordinate, 'z')
print('--刪除 z 屬性後--')
print('x = ', point1.x)
print('y = ', point1.y)
# 因為已經刪除了,所以執行後會觸發錯誤
print('z = ', point1.z)
執行後會輸出:
x = 10
Traceback (most recent call last):
y = -5
File " del.py", line 19, in <module>
z = 0
print('z = ', point1.z)
--刪除 z 屬性後--
AttributeError: 'Coordinate' object has no attribute 'z'
x = 10
y = -5
當使用函式delattr()刪除某個屬性時,如果這個屬性不存在則會報錯,例如下面的程式碼:
>>> a.name #屬性name已經刪掉,不存在
Traceback (most recent call last):
File "<pyshell#47>", line 1, in <module>
a.name
AttributeError: 'A' object has no attribute 'name'
>>> delattr(a,'name') #再刪除會報錯
Traceback (most recent call last):
File "<pyshell#48>", line 1, in <module>
delattr(a,'name')
AttributeError: name
當使用函式delattr()刪除某個屬性時,不能刪除物件的方法,否則將會出錯,例如下面的演示程式碼:
>>> a.sayHello
<bound method A.sayHello of <__main__.A object at 0x03F014B0>>
>>> delattr(a,'sayHello') #不能用於刪除方法
Traceback (most recent call last):
File "<pyshell#50>", line 1, in <module>
delattr(a,'sayHello')
AttributeError: sayHello
>>>
1.15 函式dict()
在Python程式中,函式dict()的功能是建立一個字典。在現實中有如下三種使用函式dict()的語法格式。
class dict(**kwarg)
class dict(mapping, **kwarg)
class dict(iterable, **kwarg)
- **kwargs:關鍵字;
- Mapping:元素的容器;
- Iterable:可迭代物件。
在下面的例項檔案dict.py中,演示了使用函式dict()建立字典的過程。
#不傳入任何引數時,返回空字典。
print(dict())
#可以傳入鍵值對建立字典。
print(dict(a = 1))
print(dict(a = 1,b = 2))
#可以傳入對映函式建立字典。
print(dict(zip(['a','b'],[1,2])))
#可以傳入可迭代物件建立字典。
print(dict((('a',1),('b',2))))
執行後會輸出:
{}
{'a': 1}
{'a': 1, 'b': 2}
{'a': 1, 'b': 2}
{'a': 1, 'b': 2}