物件導向捷徑


本章詳細討論Python中的各種內建函式,檔案I/O操作和過載概念。

Python內建函式

Python直譯器有許多稱為內建函式的函式,可以隨時使用。 在其最新版本中,Python包含68個內建函式,如下表所列 -

any() divmod() id() object() sorted()
ascii() enumerate() input() oct() staticmethod()
bin() eval() int() open() str()
bool() exec() isinstance() ord() sum()
bytearray() filter() issubclass() pow() super()
bytes() float() iter() print() tuple()
callable() format() len() property() type()
chr() frozenset() list() range() vars()
classmethod() getattr() locals() repr() zip()
compile() globals() map() reversed() import()
complex() hasattr() max() round( -
delattr() hash() memoryview() set() -

本節簡要介紹一些重要函式/功能 -

len()函式

len()函式獲取字串,列表或集合的長度。 它返回物件的專案的長度或數量,其中物件可以是字串,列表或集合。

>>> len(['hello', 9 , 45.0, 24])
4

len()函式內部工作方式如list.__len__()tuple.__ len __()。 因此,請注意,len()僅適用於具有__len __()方法的物件。

>>> set1
{1, 2, 3, 4}
>>> set1.__len__()
4

但是,在實踐中,我們更頃向於使用len()而不是__len __()函式,原因如下 -

  • 它更高效。 並且寫一個特定的方法來拒絕存取諸如__len__這樣的特殊方法是沒有必要的。
  • 它易於維護。
  • 它支援向後相容性。

Reversed(seq)方法

它返回反向疊代器。 seq必須是具有__reversed __()方法或支援序列協定(__len __()方法和__getitem __()方法)的物件。 當我們想從後到前迴圈專案時,它通常用於迴圈。

>>> normal_list = [2, 4, 5, 7, 9]
>>>
>>> class CustomSequence():
   def __len__(self):
      return 5
   def __getitem__(self,index):
      return "x{0}".format(index)
>>> class funkyback():
   def __reversed__(self):
      return 'backwards!'
>>> for seq in normal_list, CustomSequence(), funkyback():
      print('\n{}: '.format(seq.__class__.__name__), end="")
      for item in reversed(seq):
         print(item, end=", ")

最後的for迴圈列印正常列表的反轉列表,以及兩個自定義序列的範例。 輸出顯示revers()適用於它們中的所有三個,但是當定義__reversed__時,結果會有很大不同。

執行上面給出的程式碼時,可以觀察到以下輸出 -

list: 9, 7, 5, 4, 2,
CustomSequence: x4, x3, x2, x1, x0,
funkyback: b, a, c, k, w, a, r, d, s, !,

列舉
enumerate()方法向iterable新增一個計數器並返回列舉物件。
enumerate()的語法是 -

enumerate(iterable, start = 0)

這裡第二個引數起始是可選的,預設情況下索引從零開始(0)。

>>> # Enumerate
>>> names = ['Rajesh', 'Rahul', 'Aarav', 'Sahil', 'Trevor']
>>> enumerate(names)
<enumerate object at 0x031D9F80>
>>> list(enumerate(names))
[(0, 'Rajesh'), (1, 'Rahul'), (2, 'Aarav'), (3, 'Sahil'), (4, 'Trevor')]
>>>

因此·enumerate()·返回一個疊代器,它產生一個元組,用於保持傳遞的序列中元素的計數。 由於返回值是一個疊代器,直接存取它並沒有多大用處。 enumerate()的更好方法是將計數保持在for迴圈中。

>>> for i, n in enumerate(names):
   print('Names number: ' + str(i))
   print(n)
Names number: 0
Rajesh
Names number: 1
Rahul
Names number: 2
Aarav
Names number: 3
Sahil
Names number: 4
Trevor

標準庫中還有許多其他功能,下面是另一些更廣泛使用的功能列表 -

  • hasattrgetattrsetattrdelattr,它允許物件的屬性由其字串名稱操作。
  • allany,接受可疊代物件,如果所有或任何專案評估為真,則返回True
  • nzip,它採用兩個或多個序列並返回一個新的元組序列,其中每個元組包含每個序列的單個值。

檔案I/O

檔案的概念與術語物件導向程式設計相關。 Python封裝了作業系統在抽象中提供的介面,使我們可以使用檔案物件。

open()內建函式用於開啟檔案並返回檔案物件。 它是兩個引數中最常用的函式 -

open(filename, mode)

open()函式呼叫兩個引數,第一個是檔案名,第二個是模式。 這裡的模式可以是唯讀模式的'r',只有寫入的模式'w'(同名的現有檔案將被刪除),'a'開啟要附加的檔案,任何寫入檔案的資料都會自動新增 到最後。 'r +'開啟檔案進行讀寫。 預設模式是唯讀的。

在視窗中,模式附加的'b'以二進位制模式開啟檔案,所以也有'rb''wb''r + b'等模式。

>>> text = 'This is the first line'
>>> file = open('datawork','w')
>>> file.write(text)
22
>>> file.close()

在某些情況下,我們只想附加到現有檔案而不是覆蓋它,因為可以提供值'a'作為模式引數,附加到檔案的末尾,而不是完全覆蓋現有檔案內容。

>>> f = open('datawork','a')
>>> text1 = ' This is second line'
>>> f.write(text1)
20
>>> f.close()

當開啟一個檔案進行讀取,可以呼叫readreadlinereadlines方法來獲取檔案的內容。 read方法將檔案的全部內容作為strbytes物件返回,具體取決於第二個引數是否為'b'

為了便於閱讀,並且為了避免一次性讀取大檔案,通常最好直接在檔案物件上使用for迴圈。 對於文字檔案,它將逐行讀取每一行,並且可以在迴圈體內處理它。 但對於二進位制檔案,最好使用read()方法讀取固定大小的資料塊,並傳遞引數以獲取最大位元組數。

>>> f = open('fileone','r+')
>>> f.readline()
'This is the first line. \n'
>>> f.readline()
'This is the second line. \n'

通過對檔案物件的寫入方法寫入檔案將向該檔案寫入一個字串(二進位制資料的位元組)物件。 writelines方法接受一系列字串並將每個疊代值寫入檔案。 writelines方法不在序列中的每個專案之後追加一個新行。

最後,在完成讀取或寫入檔案時,應呼叫close()方法,以確保將任何緩衝寫入寫入磁碟,檔案已被正確清理,並將與該檔案系結的所有資源釋放回作業系統。 呼叫close()方法是一個更好的方法,但從技術上講,這將在指令碼存在時自動發生。

方法過載的替代方法
方法過載是指具有多個接受不同引數集的同名方法。

給定單個方法或函式,可以指定自己的引數數量。 根據函式定義,可以使用零個,一個,兩個或多個引數來呼叫它。

class Human:
   def sayHello(self, name = None):
      if name is not None:
         print('Hello ' + name)
      else:
         print('Hello ')

#Create Instance
obj = Human()

#Call the method, else part will be executed
obj.sayHello()

#Call the method with a parameter, if part will be executed
obj.sayHello('Rahul')

執行上面範例程式碼,得到以下結果 -

Hello
Hello Rahul

預設引數

函式也是物件
可呼叫物件是一個物件可以接受一些引數,並可能返回一個物件。 函式是Python中最簡單的可呼叫物件,但也有其他類似於類或某些類範例。

Python中的每個函式都是一個物件。 物件可以包含方法或函式,但物件不是必需的函式。

def my_func():
   print('My function was called')
my_func.description = 'A silly function'
def second_func():

   print('Second function was called')

   second_func.description = 'One more sillier function'

def another_func(func):
   print("The description:", end=" ")
   print(func.description)
   print('The name: ', end=' ')
   print(func.__name__)
   print('The class:', end=' ')
   print(func.__class__)
   print("Now I'll call the function passed in")
   func()

another_func(my_func)
another_func(second_func)

在上面的程式碼中,可以將兩個不同的函式作為引數傳遞給第三個函式,並為每個函式獲取不同的輸出 -

The description: A silly function
The name: my_func
The class: 
Now I'll call the function passed in
My function was called
The description: One more sillier function
The name: second_func
The class: 
Now I'll call the function passed in
Second function was called

可呼叫的物件

就像函式是可以在其上設定屬性的物件一樣,可以建立一個可以被呼叫的物件,就像它是一個函式一樣。

在Python中,可以使用函式呼叫語法來呼叫帶有__call __()方法的任何物件。