面向对象的快捷方式

本章详细介绍了 Python 中的各种内置函数、文件 I/O 操作和重载概念。

Python 内置函数

Python 解释器有许多可随时使用的函数,称为内置函数。在其最新版本中,Python 包含 68 个内置函数,如下表所示 −

内置函数
abs() dict() help() min() setattr()
all() dir() hex() next() slice()
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__() 方法)的对象。当我们想要从后到前循环遍历项目时,它通常在 for 循环中使用。

>>> 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('
{}: '.format(seq.__class__.__name__), end="")
      for item in reversed(seq):
         print(item, end=", ")

最后的 for 循环打印正常列表的反转列表,以及两个自定义序列的实例。输出显示 reversed() 对所有三个都有效,但当我们定义 __reversed__ 时,结果会大不相同。

输出

执行上述代码时,您可以观察到以下输出 −

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

枚举

enumerate () 方法向可迭代对象添加一个计数器并返回枚举对象。

enumerate () 的语法是 −

enumerate(iterable, start = 0)

此处第二个参数 start 是可选的,默认情况下索引以 零 (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

标准库中还有许多其他函数,这里是一些更广泛使用的函数的另一个列表 −

  • hasattr、getattr、setattrdelattr,允许通过字符串名称来操作对象的属性。

  • allany,接受可迭代对象,如果所有或任何项的计算结果为真,则返回 True

  • nzip,接受两个或更多序列并返回一个新的元组序列,其中每个元组包含来自每个序列的单个值。

文件 I/O

文件的概念与面向对象编程一词有关。 Python 已将操作系统提供的接口抽象化,使我们能够使用文件对象。

内置函数 open() 用于打开文件并返回文件对象。它是最常用的函数,有两个参数 −

open(filename, mode)

open() 函数调用两个参数,第一个是文件名,第二个是模式。这里的模式可以是"r"(表示只读模式)、"w"(表示只写)(同名的现有文件将被删除),"a"用于打开文件进行追加,写入文件的任何数据都会自动添加到末尾。"r+"用于打开文件进行读写。默认模式为只读。

在 Windows 上,将"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()

打开文件进行读取后,我们可以调用 read、readline 或 readlines 方法来获取文件的内容。 read 方法将文件的全部内容作为 str 或 bytes 对象返回,具体取决于第二个参数是否为"b"。

为了提高可读性,并避免一次读取大文件,通常最好直接在文件对象上使用 for 循环。对于文本文件,它将一次读取一行,我们可以在循环体内对其进行处理。但是对于二进制文件,最好使用 read() 方法读取固定大小的数据块,并传递要读取的最大字节数的参数。

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

通过文件对象上的 write 方法写入文件,将向文件写入一个字符串(二进制数据的字节)对象。 writelines 方法接受字符串序列并将每个迭代值写入文件。 writelines 方法不会在序列中的每个项目后附加新行。

最后,当我们完成读取或写入文件时,应该调用 close() 方法,以确保任何缓冲写入都写入磁盘,文件已被正确清理,并且与文件绑定的所有资源都已释放回操作系统。调用 close() 方法是一种更好的方法,但从技术上讲,当脚本存在时,这将自动发生。

方法重载的替代方法

方法重载是指具有多个具有相同名称的方法,它们接受不同的参数集。

给定一个方法或函数,我们可以自己指定参数的数量。根据函数定义,它可以用零个、一个、两个或多个参数来调用。

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

#创建实例
obj = Human()

#调用方法,否则将执行部分
obj.sayHello()

#使用参数调用方法,如果将执行部分
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__() 方法的对象。