1. 程式人生 > >Python標準內建函式(16-20)

Python標準內建函式(16-20)

1.16  函式dir()

在Python程式中,如果函式dir()沒有引數,則返回當前本地作用域內的名字列表。如果有引數,則嘗試返回引數所指明物件的合法屬性的列表。使用函式dir()的語法格式如下所示。

dir([object])

引數object是物件、變數或型別。如果引數object具有名為__dir__()的方法,那麼將呼叫此方法,並且必須返回屬性列表。這允許實現自定義__getattr__()或__getattribute__()函式的物件自定義dir()報告其屬性的方式。如果引數object不提供__dir__(),則函式會盡量從物件的__dict__屬性(如果已定義)和其型別物件中收集資訊。結果列表不一定是完整的,並且當物件具有自定義__getattr__()時可能會不準確。具體來說,在使用函式dir()時,根據引數的不同會返回不同的結果,具體說明如下所示:

  1. 如果引數為空則返回當前作用域內的變數、方法和定義的型別列表;
  2. 當引數是一個模組時,會返回模組的屬性、方法列表;
  3. 當引數是一個類時,會返回類及其子類的屬性、方法列表;
  4. 當在引數物件中定義了__dir__方法時,則返回__dir__方法的結果。

在下面的例項檔案dir.py中,演示了使用函式dir()返回指定列表的過程。

#當不傳引數時,返回當前作用域內的變數、方法和定義的型別列表。

print(dir())

a = 10 #定義變數a

print(dir()) #多了一個a



#當引數物件是模組時,返回模組的屬性、方法列表。

import math

print(math)

print(dir(math))



#當引數物件是類時,返回類及其子類的屬性、方法列表。

class A:

    name = 'class'



a = A()

print(dir(a))# name是類A的屬性,其他則是預設繼承的object的屬性、方法



#當物件定義了__dir__方法,則返回__dir__方法的結果

class B:

    def __dir__(self):

        return ['name','age']



b = B()

print(dir(b))#呼叫 __dir__方法

執行後會輸出:

['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']

['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a']

<module 'math' (built-in)>

['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', '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', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name']

['age', 'name']

1.17  函式divmod()

在Python程式中,函式divmod()的功能是把除數和餘數運算結果結合起來,返回一個包含商和餘數的元組(a // b, a % b)。在 python 2.3 版本之前,函式divmod()不允許處理複數。使用函式divmod()的語法格式如下所示。

divmod(a, b)

引數a和引數b都是數字,函式divmod()能夠取兩個(非複數)數字作為引數,並在使用整數除法時返回由商和餘數組成的一對數字。對於混合的運算元型別引數,採用二元算術運算子的規則。對於整數引數來說,結果與(a // b, a % b)相同。對於浮點數引數來說,結果為(q, a % b),其中q通常為math.floor(a / b),也有可能比這個結果小1。不管怎樣,q * b + a % b非常接近於a,如果a % b非0,它和b符號相同且0 <= abs(a % b) < abs(b)。

在下面的例項檔案div.py中,演示了使用函式divmod()處理數字的過程。

# 如果引數都是整數,執行的是地板除,相當於 (a//b,a%b)。

print(divmod(5,2))

print(5//2)

print(5%2)

#如果引數時浮點數,相當於( math.floor(a/b),a%b)。

import math

print(divmod(5.5,2))

print(math.floor(5.5/2))

print(5.5/2)

print(math.floor(5.5/2.0))

print(5.5%2)



print(divmod(7, 2))

print(divmod(8, 2))

print(divmod(1+2j,1+0.5j))#有些python版本不允許處理複數

執行後會輸出:

(2, 1)

2

1

(2.0, 1.5)

2

2.75

2

1.5

(3, 1)

(4, 0)

((1+0j), 1.5j)

有些Python版本不允許處理複數,檔案div.py中的最後一行程式碼執行後可能會出錯:

Traceback (most recent call last):

  File " div.py", line 15, in <module>

    print(divmod(1+2j,1+0.5j))

TypeError: can't take floor or mod of complex number.

1.18  函式enumerate()

在Python程式中,函式enumerate()的功能是將一個可遍歷的資料物件(如列表、元組或字串)組合為一個索引序列,同時列出資料和資料下標,一般被用在 for 迴圈中。使用函式enumerate()的語法格式如下所示:

enumerate(sequence, [start=0])
  1. sequence:必須是一個序列、一個迭代器,或者其它某種支援迭代的物件;
  2. start:下標起始位置。

函式enumerate()會返回一個列舉物件,enumerate()返回的迭代器的__next__()方法返回一個元組,該元組包含一個計數(從start開始,預設為0)和迭代“sequence”得到的值。例如在下面的例項檔案num.py中,演示了使用函式enumerate()處理資料的過程。

#基本用法

seasons = ['Spring', 'Summer', 'Fall', 'Winter']

print(list(enumerate(seasons)))

print(list(enumerate(seasons, start=1)))# 小標從 1 開始



#普通的 for 迴圈

i = 0

seq = ['one', 'two', 'three']

for element in seq:

     print(i, seq[i])

     i += 1



#在for迴圈使用 enumerate

seq = ['one', 'two', 'three']

for i, element in enumerate(seq):

     print(i, seq[i])



#已知lst = [1,2,3,4,5,6],要求輸出:

0,1

1,2

2,3

3,4

4,5

5,6

#

lst = [1,2,3,4,5,6]

for index,value in enumerate(lst):

  print ('%s,%s' % (index,value))



#從指定索引從1開始

lst = [1,2,3,4,5,6]

for index,value in enumerate(lst,1):

  print ('%s,%s' % (index,value))



#從指定索引從3開始

for index,value in enumerate(lst,3):

  print ('%s,%s' % (index,value))

執行後會輸出:

[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]

[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]

0 one

1 two

2 three

0 one

1 two

2 three

0,1

1,2

2,3

3,4

4,5

5,6

1,1

2,2

3,3

4,4

5,5

6,6

3,1

4,2

5,3

6,4

7,5

8,6

1.19  函式eval()

在Python程式中,函式eval()的功能是執行一個字串表示式,並返回表示式的值。使用函式eval()的語法格式如下所示。

eval(expression, globals=None, locals=None)
  1. expression:表示式;
  2. globals:變數作用域,全域性名稱空間,如果被提供則必須是一個字典物件;
  3. locals:變數作用域,區域性名稱空間。如果有區域性變數,則locals可以是任何對映型別物件。

在函式eval()中,引數“expression”被當作Python表示式來解析並演算(技術上來說,是個條件列表),使用globals和locals字典作為全域性和區域性的名稱空間。如果globals字典存在,且缺少‘__builtins__’,在expression被解析之前,當前的全域性變數被拷貝進globals。這說明expression通常具有對標準builtins的完全訪問許可權,並且傳播受限環境。如果locals字典被忽略,則預設是globals字典。如果兩個字典都省略,則在呼叫eval()的環境中執行表示式。返回值是被演算的表示式的結果。

在下面的例項檔案eval.py中,演示了使用函式eval()處理字串的過程。

x = 7

print(eval( '3 * x' ))

print(eval('pow(2,2)'))

print(eval('2 + 2'))

n=81

print(eval("n + 4"))

執行後會輸出:

21

4

4

85

在Python程式中,當某行程式碼要使用變數 x 的值時,Python 會到所有可用的名字空間去查詢變數,按照如下所示的順序執行:

(1)區域性名字空間:特指當前函式或類的方法。如果函式定義了一個區域性變數 x, 或一個引數 x,Python 將使用它,然後停止搜尋。

(2)全域性名字空間:特指當前的模組。如果模組定義了一個名為x 的變數,函式或類,Python 將使用它然後停止搜尋。

(3)內建名字空間:對每個模組都是全域性的。作為最後的嘗試,Python:將假設x是內建函式或變數。

在下面的例項檔案eval1.py中,演示了使用函式eval()將字串轉成相應的物件(如list、tuple、dict和string之間的轉換)的過程。

a = "[[1,2], [3,4], [5,6], [7,8], [9,0]]"

b = eval(a)

print(b)

a = "{1:'xx',2:'yy'}"

c = eval(a)

print(c)

a = "(1,2,3,4)"

d = eval(a)

print(d)

執行後會輸出:

[[1, 2], [3, 4], [5, 6], [7, 8], [9, 0]]

{1: 'xx', 2: 'yy'}

(1, 2, 3, 4)

在下面的例項檔案eval2.py中,演示了使用反引號轉換的字串再反轉回物件的過程。

list1 = [1,2,3,4,5]

print('list1')

'[1, 2, 3, 4, 5]'

print(type('list1'))

print(type(eval('list1')))

a = eval('list1')

print(a)

執行後會輸出:

list1

<class 'str'>

<class 'list'>

[1, 2, 3, 4, 5]

1.20  函式exec()

在Python程式中,函式exec()的功能是執行儲存在字串或檔案中的Python語句,和函式eval()相比,函式exec()可以執行更復雜的Python程式碼。使用函式exec()的語法格式如下所示。

exec(object[, globals[, locals]])
  1. object:必選引數,表示需要被指定的Python程式碼,必須是字串或code物件。如果object是一個字串,則該字串會先被解析為一組Python語句,然後在執行(除非發生語法錯誤)。如果object是一個code物件,那麼它只是被簡單的執行;
  2. globals:可選引數,表示全域性名稱空間(存放全域性變數),如果被提供,則必須是一個字典物件;
  3. locals:可選引數,表示當前區域性名稱空間(存放區域性變數),如果被提供,可以是任何對映物件。如果該引數被忽略,那麼它將會取與globals相同的值。

在下面的例項檔案exec.py中,演示了使用函式exec()執行Python程式語句的過程。

# 單行語句字串

exec('print("Hello World")')

exec("print ('runoob.com')")

#多行語句字串

exec("""for i in range(5):

     print ("iter time: %d" % i)

 """)



x = 10

expr = """

z = 30

sum = x + y + z

print(sum)

"""





def func():

    y = 20

    exec(expr)

    exec(expr, {'x': 1, 'y': 2})

    exec(expr, {'x': 1, 'y': 2}, {'y': 3, 'z': 4})



func()

執行後會輸出:

Hello World

runoob.com

iter time: 0

iter time: 1

iter time: 2

iter time: 3

iter time: 4

60

33

34