Object Oriented Python 简明教程

Object Oriented Python - Quick Guide

Object Oriented Python - Introduction

编程语言不断涌现,不同的方法学也是如此。面向对象编程就是这样一种方法,在过去几年中变得非常流行。

Programming languages are emerging constantly, and so are different methodologies.Object-oriented programming is one such methodology that has become quite popular over past few years.

本节讲述 Python 编程语言作为面向对象编程语言的特性。

This chapter talks about the features of Python programming language that makes it an object-oriented programming language.

Language Programming Classification Scheme

Python 可归类为面向对象编程方法。下图说明了各种编程语言的特性。观察 Python 中使其成为面向对象的特性。

Python can be characterized under object-oriented programming methodologies. The following image shows the characteristics of various programming languages. Observe the features of Python that makes it object-oriented.

Langauage Classes

Categories

Langauages

Programming Paradigm

Procedural

C, C++, C#, Objective-C, java, Go

Scripting

CoffeeScript, JavaScript, Python, Perl, Php, Ruby

Functional

Clojure, Eralang, Haskell, Scala

Compilation Class

Static

C, C++, C#, Objective-C, java, Go, Haskell, Scala

Dynamic

CoffeeScript, JavaScript, Python, Perl, Php, Ruby, Clojure, Erlang

Type Class

Strong

C#, java, Go, Python, Ruby, Clojure, Erlang, Haskell, Scala

Weak

C, C++, C#, Objective-C, CoffeeScript, JavaScript, Perl, Php

Memory Class

Managed

Others

Unmanaged

What is Object Oriented Programming?

Object Oriented 意味着面向对象。换句话说,这就是对于对对象建模来说在功能上的方向。这是通过描述一组交互对象及其数据和行为对复杂系统建模时所用的众多技术之一。

Object Oriented means directed towards objects. In other words, it means functionally directed towards modelling objects. This is one of the many techniques used for modelling complex systems by describing a collection of interacting objects via their data and behavior.

Python,一种面向对象编程(OOP),是专注于使用对象和类来进行设计和构建应用程序的编程方法。面向对象编程(OOP)的主要支柱是 Inheritance, Polymorphism, Abstraction,Encapsulation

Python, an Object Oriented programming (OOP), is a way of programming that focuses on using objects and classes to design and build applications.. Major pillars of Object Oriented Programming (OOP) are Inheritance, Polymorphism, Abstraction, ad Encapsulation.

面向对象分析(OOA)是对问题、系统或任务进行检验并识别其对象和交互的过程。

Object Oriented Analysis(OOA) is the process of examining a problem, system or task and identifying the objects and interactions between them.

Why to Choose Object Oriented Programming?

Python是在面向对象方法的基础上设计的。OOP具有以下优势-

Python was designed with an object-oriented approach. OOP offers the following advantages −

  1. Provides a clear program structure, which makes it easy to map real world problems and their solutions.

  2. Facilitates easy maintenance and modification of existing code.

  3. Enhances program modularity because each object exists independently and new features can be added easily without disturbing the existing ones.

  4. Presents a good framework for code libraries where supplied components can be easily adapted and modified by the programmer.

  5. Imparts code reusability

Procedural vs. Object Oriented Programming

基于过程的编程源于结构化编程,基于 functions/procedure/routines 的概念。在面向过程的编程中,访问和更改数据非常容易。另一方面,面向对象编程(OOP)允许将问题分解为若干称为 objects 的单元,然后围绕这些对象构建数据和函数。它更强调数据而不是过程或函数。同样,在 OOP 中,数据是隐藏的,外部过程无法访问。

Procedural based programming is derived from structural programming based on the concepts of functions/procedure/routines. It is easy to access and change the data in procedural oriented programming. On the other hand, Object Oriented Programming (OOP) allows decomposition of a problem into a number of units called objects and then build the data and functions around these objects. It emphasis more on the data than procedure or functions. Also in OOP, data is hidden and cannot be accessed by external procedure.

下图中的表格显示了 POP 和 OOP 方法之间的主要区别。

The table in the following image shows the major differences between POP and OOP approach.

面向过程编程(POP)和面向对象编程(OOP)之间的差异。

Difference between Procedural Oriented Programming(POP)vs. Object Oriented Programming(OOP).

Procedural Oriented Programming

ObjectOriented Programming

Based On

In Pop,entire focus is on data and functions

Oops is based on a real world scenario.Whole program is divided into small parts called object

Reusability

Limited Code reuse

Code reuse

Approach

Top down Approach

Object focused Design

Access specifiers

Not any

Public, private and Protected

Data movement

Data can move freely from functions to function in the system

In Oops, data can move and communicate with each other through member functions

Data Access

In pop, most functions uses global data for sharing that can be accessed freely from function to function in the system

In Oops,data cannot move freely from method to method,it can be kept in public or private so we can control the access of data

Data Hiding

In pop, so specific way to hide data, so little bit less secure

It provides data hiding, so much more secure

Overloading

Not possible

Functions and Operator Overloading

Example-Languages

C, VB, Fortran, Pascal

C++, Python, Java, C#

Abstraction

Uses abstraction at procedure level

Uses abstraction at class and object Level

Principles of Object Oriented Programming

面向对象编程 (OOP) 基于 objects 而不是操作以及 data 而不是逻辑的概念。为了让编程语言面向对象,它应当具备一种机制来实现使用类和对象以及实现和使用基本面向对象原则和概念(即继承、抽象、封装和多态性)。

Object Oriented Programming (OOP) is based on the concept of objects rather than actions, and data rather than logic. In order for a programming language to be object-oriented, it should have a mechanism to enable working with classes and objects as well as the implementation and usage of the fundamental object-oriented principles and concepts namely inheritance, abstraction, encapsulation and polymorphism.

oops

让我们简要了解面向对象编程的各个支柱 -

Let us understand each of the pillars of object-oriented programming in brief −

Encapsulation

此属性隐藏了不必要详细信息,并让对程序结构的管理变得更轻松。每个对象实现和状态都隐藏在定义明确的界限之后,并提供了一个用于使用它们的清晰而简单的接口。实现此操作的一种方式是使数据私有。

This property hides unnecessary details and makes it easier to manage the program structure. Each object’s implementation and state are hidden behind well-defined boundaries and that provides a clean and simple interface for working with them. One way to accomplish this is by making the data private.

Inheritance

继承也称为泛化,它允许我们捕获类和对象之间的层级关系。例如,“水果”就是“橙子”的一项概括。继承从代码重用角度来看非常有用。

Inheritance, also called generalization, allows us to capture a hierarchal relationship between classes and objects. For instance, a ‘fruit’ is a generalization of ‘orange’. Inheritance is very useful from a code reuse perspective.

Abstraction

此属性允许我们隐藏详细信息并仅公开某个概念或对象的关键特征。例如,驾驶滑板车的人知道按喇叭会发出声音,但他不知道按喇叭实际上如何产生声音。

This property allows us to hide the details and expose only the essential features of a concept or object. For example, a person driving a scooter knows that on pressing a horn, sound is emitted, but he has no idea about how the sound is actually generated on pressing the horn.

Polymorphism

多态性指多种形式。也就是说,一项事物或操作会以不同的形式或方式存在。构造函数类重载就是一个很好的多态性例子。

Poly-morphism means many forms. That is, a thing or action is present in different forms or ways. One good example of polymorphism is constructor overloading in classes.

Object-Oriented Python

Python 编程的核心是 objectOOP ,但您不必将自己限制在通过将代码整理成类来使用 OOP。OOP 增强了 Python 的整体设计理念,并支持以整洁有效的方式编程。OOP 还支持编写更大型且更复杂的程序。

The heart of Python programming is object and OOP, however you need not restrict yourself to use the OOP by organizing your code into classes. OOP adds to the whole design philosophy of Python and encourages a clean and pragmatic way to programming. OOP also enables in writing bigger and complex programs.

Modules vs. Classes and Objects

Modules are like “Dictionaries”

在使用模块时,注意以下要点 -

When working on Modules, note the following points −

  1. A Python module is a package to encapsulate reusable code.

  2. Modules reside in a folder with a init.py file on it.

  3. Modules contain functions and classes.

  4. Modules are imported using the import keyword.

回想一下,字典是一个 key-value 对。这意味着,如果您有一个键为 EmployeID 的字典,并且您想要检索它,那么您将必须使用下列代码行 −

Recall that a dictionary is a key-value pair. That means if you have a dictionary with a key EmployeID and you want to retrieve it, then you will have to use the following lines of code −

employee = {“EmployeID”: “Employee Unique Identity!”}
print (employee [‘EmployeID])

您将需要按照以下过程处理 modules −

You will have to work on modules with the following process −

  1. A module is a Python file with some functions or variables in it.

  2. Import the file you need.

  3. Now, you can access the functions or variables in that module with the ‘.’ (dot) Operator.

考虑一个名为 employee.py 的 module,其中有一个名为 employee 的函数。该函数的代码如下所示 −

Consider a module named employee.py with a function in it called employee. The code of the function is given below −

# this goes in employee.py
def EmployeID():
   print (“Employee Unique Identity!”)

现在导入 module,然后访问函数 EmployeID

Now import the module and then access the function EmployeID

import employee
employee. EmployeID()

您可以像所示的那样,在其中插入一个名为 Age 的变量 −

You can insert a variable in it named Age, as shown −

def EmployeID():
   print (“Employee Unique Identity!”)
# just a variable
Age = “Employee age is **”

现在,请以下面的方式访问该变量 −

Now, access that variable in the following way −

import employee
employee.EmployeID()
print(employee.Age)

现在,让我们将它与字典进行比较 −

Now, let’s compare this to dictionary −

Employee[‘EmployeID’] # get EmployeID from employee
Employee.employeID() # get employeID from the module
Employee.Age # get access to variable

请注意,Python 中有一个通用的模式 −

Notice that there is common pattern in Python −

  1. Take a key = value style container

  2. Get something out of it by the key’s name

当将 module 与字典进行比较时,两者相似,但有以下几点除外 −

When comparing module with a dictionary, both are similar, except with the following −

  1. In the case of the dictionary, the key is a string and the syntax is [key].

  2. In the case of the module, the key is an identifier, and the syntax is .key.

Classes are like Modules

模块是可存储 Python 代码的专门词典,你可以用“.”操作符访问它。类是一种将函数和数据分组放置在容器中以便你可以用“.”操作符访问它们的方式。

Module is a specialized dictionary that can store Python code so you can get to it with the ‘.’ Operator. A class is a way to take a grouping of functions and data and place them inside a container so you can access them with the ‘.‘operator.

如果你必须创建一个类似于员工模块的类,可以使用以下代码创建:

If you have to create a class similar to the employee module, you can do it using the following code −

class employee(object):
   def __init__(self):
      self. Age = “Employee Age is ##”
   def EmployeID(self):
      print (“This is just employee unique identity”)

Note - 类比模块更受青睐,因为你可以原封不动地重复使用它们,而且不会造成太多干扰。对于模块,你只能将它们与整个程序合二为一。

Note − Classes are preferred over modules because you can reuse them as they are and without much interference. While with modules, you have only one with the entire program.

Objects are like Mini-imports

类类似于 mini-module ,你可以用 instantiate 中提到的概念以类似于导入类的方式导入类。注意,当你实例化一个类时,你可以获得 object

A class is like a mini-module and you can import in a similar way as you do for classes, using the concept called instantiate. Note that when you instantiate a class, you get an object.

你可以实例化一个对象,类似于像调用函数那样调用一个类,如下所示:

You can instantiate an object, similar to calling a class like a function, as shown −

this_obj = employee() # Instantiatethis_obj.EmployeID() # get EmployeId from the class
print(this_obj.Age) # get variable Age

你可以使用以下三种方式中的任何一种:

You can do this in any of the following three ways −

# dictionary style
Employee[‘EmployeID’]
# module style
Employee.EmployeID()
Print(employee.Age)
# Class style
this_obj = employee()
this_obj.employeID()
Print(this_obj.Age)

Object Oriented Python - Environment Setup

本章将详细解释如何在您的本地计算机上设置 Python 环境。

This chapter will explain in detail about setting up the Python environment on your local computer.

Prerequisites and Toolkits

在继续学习 Python 之前,我们建议您检查是否满足以下先决条件−

Before you proceed with learning further on Python, we suggest you to check whether the following prerequisites are met −

  1. Latest version of Python is installed on your computer

  2. An IDE or text editor is installed

  3. You have basic familiarity to write and debug in Python, that is you can do the following in Python − Able to write and run Python programs. Debug programs and diagnose errors. Work with basic data types. Write for loops, while loops, and if statements Code functions

如果您没有任何编程语言经验,您可以在

If you don’t have any programming language experience, you can find lots of beginner tutorials in Python on

Installing Python

以下步骤详细介绍了如何在本地计算机上安装 Python−

The following steps show you in detail how to install Python on your local computer −

Step 1 − 前往官方 Python 网站 https://www.python.org/ ,单击 Downloads 菜单,然后选择最新或任何稳定的版本。

Step 1 − Go to the official Python website https://www.python.org/, click on the Downloads menu and choose the latest or any stable version of your choice.

python website

Step 2 − 保存您正在下载的 Python 安装程序 exe 文件,下载完成后将其打开。单击 Run ,并默认选择 Next 选项,然后完成安装。

Step 2 − Save the Python installer exe file that you’re downloading and once you have downloaded it, open it. Click on Run and choose Next option by default and finish the installation.

python installer

Step 3 − 安装后,您现在应该会看到如下图所示的 Python 菜单。通过选择 IDLE(Python GUI)来启动程序。

Step 3 − After you have installed, you should now see the Python menu as shown in the image below. Start the program by choosing IDLE (Python GUI).

idle

这将启动 Python shell。键入简单命令来检查安装。

This will start the Python shell. Type in simple commands to check the installation.

python shell

Choosing an IDE

集成开发环境是一个面向软件开发的文本编辑器。您必须安装一个 IDE 来控制您的编程流程,并在处理 Python 时对项目分组。以下是网上提供的一些 IDE。您可以根据自己的需要选择一个。

An Integrated Development Environment is a text editor geared towards software development. You will have to install an IDE to control the flow of your programming and to group projects together when working on Python. Here are some of IDEs avaialable online. You can choose one at your convenience.

  1. Pycharm IDE

  2. Komodo IDE

  3. Eric Python IDE

Note − Eclipse IDE 主要用于 Java,但它有一个 Python 插件。

Note − Eclipse IDE is mostly used in Java, however it has a Python plugin.

Pycharm

pycharm

Pycharm 跨平台 IDE 是目前最流行的 IDE 之一。它通过代码完成、项目和代码导航、集成单元测试、版本控制集成、调试等提供编码辅助和分析

Pycharm, the cross-platform IDE is one of the most popular IDE currently available. It provides coding assistance and analysis with code completion, project and code navigation, integrated unit testing, version control integration, debugging and much more

Languages Supported − Python、HTML、CSS、JavaScript、Coffee Script、TypeScript、Cython、AngularJS、Node.js、模板语言。

Languages Supported − Python, HTML, CSS, JavaScript, Coffee Script, TypeScript, Cython,AngularJS, Node.js, template languages.

Screenshot

screenshot

Why to Choose?

PyCharm 为其用户提供以下功能和好处−

PyCharm offers the following features and benefits for its users −

  1. Cross platform IDE compatible with Windows, Linux, and Mac OS

  2. Includes Django IDE, plus CSS and JavaScript support

  3. Includes thousands of plugins, integrated terminal and version control

  4. Integrates with Git, SVN and Mercurial

  5. Offers intelligent editing tools for Python

  6. Easy integration with Virtualenv, Docker and Vagrant

  7. Simple navigation and search features

  8. Code analysis and refactoring

  9. Configurable injections

  10. Supports tons of Python libraries

  11. Contains Templates and JavaScript debuggers

  12. Includes Python/Django debuggers

  13. Works with Google App Engine, additional frameworks and libraries.

  14. Has customizable UI, VIM emulation available

Komodo IDE

komode

这是一款多语言 IDE,支持 100 多种语言,并且基本适用于动态语言(如 Python、PHP 和 Ruby)。这是一款商业 IDE,可免费试用 21 天,并提供完整功能。ActiveState 是管理 Komodo IDE 开发的软件公司。它还提供 Komodo 的精简版本,称为 Komodo Edit,可用于简单的编程任务。

It is a polyglot IDE which supports 100+ languages and basically for dynamic languages such as Python, PHP and Ruby. It is a commercial IDE available for 21 days free trial with full functionality. ActiveState is the software company managing the development of the Komodo IDE. It also offers a trimmed version of Komodo known as Komodo Edit for simple programming tasks.

这款 IDE 包含各种功能,从最基本到高级级别。如果您是学生或自由职业者,则可以购买价格几乎是实际价格一半的产品。但是,对于受认可机构和大学的老师和教授来说,它是完全免费的。

This IDE contains all kinds of features from most basic to advanced level. If you are a student or a freelancer, then you can buy it almost half of the actual price. However, it’s completely free for teachers and professors from recognized institutions and universities.

它具有进行 Web 和移动开发所需的所有功能,包括对所有语言和框架的支持。

It got all the features you need for web and mobile development, including support for all your languages and frameworks.

Komodo Edit(免费版本)和 Komodo IDE(付费版本)的下载链接如下所示 −

The download links for Komodo Edit(free version) and Komodo IDE(paid version) are as given here −

Komodo Edit (free)

Komodo Edit (free)

Komodo IDE (paid)

Komodo IDE (paid)

Screenshot

komodo ide

Why to Choose?

  1. Powerful IDE with support for Perl, PHP, Python, Ruby and many more.

  2. Cross-Platform IDE.

它包括基本功能,如集成调试器支持、自动完成、文档对象模型 (DOM) 查看器、代码浏览器、交互式 shell、断点配置、代码分析、集成单元测试。简而言之,它是一款专业 IDE,具有大量提高生产力的功能。

It includes basic features like integrated debugger support, auto complete, Document Object Model(DOM) viewer, code browser, interactive shells, breakpoint configuration, code profiling, integrated unit testing. In short, it is a professional IDE with a host of productivity-boosting features.

Eric Python IDE

eric

这是一款用于 Python 和 Ruby 的开源 IDE。Eric 是一个全功能编辑器和 IDE,用 Python 编写。它基于跨平台 Qt GUI 工具包,集成了高度灵活的 Scintilla 编辑器控件。这款 IDE 非常可配置,用户可以选择使用哪些功能,以及不使用哪些功能。您可以从以下链接下载 Eric IDE:

It is an open-source IDE for Python and Ruby. Eric is a full featured editor and IDE, written in Python. It is based on the cross platform Qt GUI toolkit, integrating the highly flexible Scintilla editor control. The IDE is very much configurable and one can choose what to use and what not. You can download Eric IDE from below link:

Why to Choose

  1. Great indentation, error highlighting.

  2. Code assistance

  3. Code completion

  4. Code cleanup with PyLint

  5. Quick search

  6. Integrated Python debugger.

Screenshot

why to choose

Choosing a Text Editor

您可能并不总需要 IDE。例如,学习使用 Python 或 Arduino 进行编码的任务,或者在 shell 脚本中处理快速脚本以帮助您自动执行某些任务时,一款简单且轻量级的以代码为中心的文本编辑器就足够了。此外,许多文本编辑器提供诸如语法高亮显示和程序内脚本执行等功能,类似于 IDE。以下列出了一些文本编辑器 −

You may not always need an IDE. For tasks such as learning to code with Python or Arduino, or when working on a quick script in shell script to help you automate some tasks a simple and light weight code-centric text editor will do. Also many text editors offer features such as syntax highlighting and in-program script execution, similar to IDEs. Some of the text editors are given here −

  1. Atom

  2. Sublime Text

  3. Notepad++

Atom Text Editor

atom

Atom 是一款由 GitHub 团队开发的可破解文本编辑器。这是一款免费且开放源代码的文本和代码编辑器,这意味着您可以查看所有代码、针对您自己的用途进行修改,甚至还可以提供改进建议。这是一款适用于 macOS、Linux 和 Microsoft Windows 的跨平台文本编辑器,支持以 Node.js 编写的外挂程序和嵌入式 Git 控制。

Atom is a hackable text editor built by the team of GitHub. It is a free and open source text and code editor which means that all the code is available for you to read, modify for your own use and even contribute improvements. It is a cross-platform text editor compatible for macOS, Linux, and Microsoft Windows with support for plug-ins written in Node.js and embedded Git Control.

Screenshot

download link

Languages Supported

C/C++、C#、CSS、CoffeeScript、HTML、JavaScript、Java、JSON、Julia、Objective-C、PHP、Perl、Python、Ruby on Rails、Ruby、Shell 脚本、Scala、SQL、XML、YAML 等多种语言。

C/C++, C#, CSS, CoffeeScript, HTML, JavaScript, Java, JSON, Julia, Objective-C, PHP, Perl, Python, Ruby on Rails, Ruby, Shell script, Scala, SQL, XML, YAML and many more.

Sublime Text Editor

sublime

Sublime Text 是一个专有软件,它提供了免费试用版,让您在购买前进行测试。根据 stackoverflow.com 的说法,它是第四大最受欢迎的开发环境。

Sublime text is a proprietary software and it offers you a free trial version to test it before you purchase it. According to stackoverflow.com, it’s the fourth most popular Development Environment.

它提供的一些优势包括其令人难以置信的速度、易用性和社区支持。它还支持多种编程语言和标记语言,用户可以通过插件添加函数,这些插件通常由社区创建并在自由软件许可下维护。

Some of the advantages it provides is its incredible speed, ease of use and community support. It also supports many programming languages and mark-up languages, and functions can be added by users with plugins, typically community-built and maintained under free-software licenses.

Screenshot

freesoftware licenses

Language supported

  1. Python, Ruby, JavaScript etc.

Why to Choose?

  1. Customize key bindings, menus, snippets, macros, completions and more.

  2. Auto completion feature

  3. Quickly Insert Text & code with sublime text snippets using snippets, field markers and place holders

  4. Opens Quickly

  5. Cross Platform support for Mac, Linux and Windows.

  6. Jump the cursor to where you want to go

  7. Select Multiple Lines, Words and Columns

Notepad ++

notepad

这是一款免费源代码编辑器,取代记事本,支持多种语言,从汇编语言到 XML,包括 Python。在 MS Windows 环境中运行,其使用受 GPL 许可约束。除语法高亮显示外,Notepad++ 还拥有对编码人员特别有用的某些功能。

It’s a free source code editor and Notepad replacement that supports several languages from Assembly to XML and including Python. Running in the MS windows environment, its use is governed by GPL license. In addition to syntax highlighting, Notepad++ has some features that are particularly useful to coders.

Screenshot

notepad plusplus

Key Features

  1. Syntax highlighting and syntax folding

  2. PCRE (Perl Compatible Regular Expression) Search/Replace

  3. Entirely customizable GUI

  4. SAuto completion

  5. Tabbed editing

  6. Multi-View

  7. Multi-Language environment

  8. Launchable with different arguments

Language Supported

  1. Almost every language (60+ languages) like Python, C, C++, C#, Java etc.

Object Oriented Python - Data Structures

从语法角度来看,Python 数据结构非常直观,它们提供大量操作选择。您需要根据数据的内容、是否需要修改数据、数据是否固定以及需要什么访问类型(例如,开始/结束/随机等)来选择 Python 数据结构。

Python data structures are very intuitive from a syntax point of view and they offer a large choice of operations. You need to choose Python data structure depending on what the data involves, if it needs to be modified, or if it is a fixed data and what access type is required, such as at the beginning/end/random etc.

Lists

在 Python 中,列表代表最通用的数据结构类型。列表是一个容器,它在方括号中保存逗号分隔的值(项或元素)。当我们需要使用多个相关值时,列表会非常有用。由于列表将数据保存在一起,我们可以一次对多个值执行相同的方法和操作。列表索引从零开始,与字符串不同,列表是可变的。

A List represents the most versatile type of data structure in Python. A list is a container which holds comma-separated values (items or elements) between square brackets. Lists are helpful when we want to work with multiple related values. As lists keep data together, we can perform the same methods and operations on multiple values at once. Lists indices start from zero and unlike strings, lists are mutable.

Data Structure - List

>>>
>>> # Any Empty List
>>> empty_list = []
>>>
>>> # A list of String
>>> str_list = ['Life', 'Is', 'Beautiful']
>>> # A list of Integers
>>> int_list = [1, 4, 5, 9, 18]
>>>
>>> #Mixed items list
>>> mixed_list = ['This', 9, 'is', 18, 45.9, 'a', 54, 'mixed', 99, 'list']
>>> # To print the list
>>>
>>> print(empty_list)
[]
>>> print(str_list)
['Life', 'Is', 'Beautiful']
>>> print(type(str_list))
<class 'list'>
>>> print(int_list)
[1, 4, 5, 9, 18]
>>> print(mixed_list)
['This', 9, 'is', 18, 45.9, 'a', 54, 'mixed', 99, 'list']

Accessing Items in Python List

列表的每个项都分配了一个数字,即该数字的索引或位置。索引始终从零开始,第二个索引为一,依此类推。要访问列表中的项,我们可以在方括号内使用这些索引号。例如,观察以下代码:

Each item of a list is assigned a number – that is the index or position of that number.Indexing always start from zero, the second index is one and so forth. To access items in a list, we can use these index numbers within a square bracket. Observe the following code for example −

>>> mixed_list = ['This', 9, 'is', 18, 45.9, 'a', 54, 'mixed', 99, 'list']
>>>
>>> # To access the First Item of the list
>>> mixed_list[0]
'This'
>>> # To access the 4th item
>>> mixed_list[3]
18
>>> # To access the last item of the list
>>> mixed_list[-1]
'list'

Empty Objects

空对象是最简单、最基本的 Python 内置类型。我们已经多次在不知不觉中使用它们,并且已将它们扩展到我们创建的每个类。编写空类的主要目的是暂时阻止某些内容,并在稍后对其进行扩展并添加行为。

Empty Objects are the simplest and most basic Python built-in types. We have used them multiple times without noticing and have extended it to every class we have created. The main purpose to write an empty class is to block something for time being and later extend and add a behavior to it.

向类添加行为意味着用一个对象替换一个数据结构,并更改对它的所有引用。所以在创建任何内容之前,检查数据是否伪装成一个对象非常重要。观察以下代码以增强理解:

To add a behavior to a class means to replace a data structure with an object and change all references to it. So it is important to check the data, whether it is an object in disguise, before you create anything. Observe the following code for better understanding:

>>> #Empty objects
>>>
>>> obj = object()
>>> obj.x = 9
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
obj.x = 9
AttributeError: 'object' object has no attribute 'x'

因此,从上面我们可以看出,不可能对直接实例化的对象设置任何属性。当 Python 允许一个对象拥有任意属性时,它会占用一定数量的系统内存来跟踪每个对象具有的属性,以便同时存储属性名称和属性值。即使没有存储任何属性,也会为潜在的新属性分配一定数量的内存。

So from above, we can see it’s not possible to set any attributes on an object that was instantiated directly. When Python allows an object to have arbitrary attributes, it takes a certain amount of system memory to keep track of what attributes each object has, for storing both the attribute name and its value. Even if no attributes are stored, a certain amount of memory is allocated for potential new attributes.

所以,Python 默认情况下禁用对象和其他几个内置对象的任意属性。

So Python disables arbitrary properties on object and several other built-ins, by default.

>>> # Empty Objects
>>>
>>> class EmpObject:
    pass
>>> obj = EmpObject()
>>> obj.x = 'Hello, World!'
>>> obj.x
'Hello, World!'

因此,如果我们要将属性分组在一起,我们可以将它们存储在一个空对象中,如上所示的代码中。但是,并不总是建议使用此方法。请记住,只有当您想要同时指定数据和行为时,才应该使用类和对象。

Hence, if we want to group properties together, we could store them in an empty object as shown in the code above. However, this method is not always suggested. Remember that classes and objects should only be used when you want to specify both data and behaviors.

Tuples

元组与列表类似,可存储元素。但是,它们是不可变的,所以我们无法添加、删除或替换对象。元组提供的不可变性的主要好处是我们可以将其用作字典的键,或在对象需要哈希值的其他位置。

Tuples are similar to lists and can store elements. However, they are immutable, so we cannot add, remove or replace objects. The primary benefits tuple provides because of its immutability is that we can use them as keys in dictionaries, or in other locations where an object requires a hash value.

元组用于存储数据,而不是行为。如果您需要行为来操作元组,则需要将元组传递给执行操作的函数(或另一个对象上的方法)。

Tuples are used to store data, and not behavior. In case you require behavior to manipulate a tuple, you need to pass the tuple into a function(or method on another object) that performs the action.

由于元组可以作为字典键,因此存储的值彼此不同。我们可以通过用逗号分隔值来创建元组。元组用括号括住,但不是强制的。以下代码显示了两个相同的赋值。

As tuple can act as a dictionary key, the stored values are different from each other. We can create a tuple by separating the values with a comma. Tuples are wrapped in parentheses but not mandatory. The following code shows two identical assignments .

>>> stock1 = 'MSFT', 95.00, 97.45, 92.45
>>> stock2 = ('MSFT', 95.00, 97.45, 92.45)
>>> type (stock1)
<class 'tuple'>
>>> type(stock2)
<class 'tuple'>
>>> stock1 == stock2
True
>>>

Defining a Tuple

元组与列表非常相似,除了整套元素用括号括住而不是用方括号括住。

Tuples are very similar to list except that the whole set of elements are enclosed in parentheses instead of square brackets.

就像切片列表时,你会得到一个新列表,切片元组时,你会得到一个新元组。

Just like when you slice a list, you get a new list and when you slice a tuple, you get a new tuple.

>>> tupl = ('Tuple','is', 'an','IMMUTABLE', 'list')
>>> tupl
('Tuple', 'is', 'an', 'IMMUTABLE', 'list')
>>> tupl[0]
'Tuple'
>>> tupl[-1]
'list'
>>> tupl[1:3]
('is', 'an')

Python Tuple Methods

以下代码显示了 Python 元组中的方法:

The following code shows the methods in Python tuples −

>>> tupl
('Tuple', 'is', 'an', 'IMMUTABLE', 'list')
>>> tupl.append('new')
Traceback (most recent call last):
   File "<pyshell#148>", line 1, in <module>
      tupl.append('new')
AttributeError: 'tuple' object has no attribute 'append'
>>> tupl.remove('is')
Traceback (most recent call last):
   File "<pyshell#149>", line 1, in <module>
      tupl.remove('is')
AttributeError: 'tuple' object has no attribute 'remove'
>>> tupl.index('list')
4
>>> tupl.index('new')
Traceback (most recent call last):
   File "<pyshell#151>", line 1, in <module>
      tupl.index('new')
ValueError: tuple.index(x): x not in tuple
>>> "is" in tupl
True
>>> tupl.count('is')
1

从上面显示的代码中,我们可以理解元组是不可变的,因此:

From the code shown above, we can understand that tuples are immutable and hence −

  1. You cannot add elements to a tuple.

  2. You cannot append or extend a method.

  3. You cannot remove elements from a tuple.

  4. Tuples have no remove or pop method.

  5. Count and index are the methods available in a tuple.

Dictionary

字典是 Python 的内置数据类型之一,它定义了键和值之间的一对一关系。

Dictionary is one of the Python’s built-in data types and it defines one-to-one relationships between keys and values.

Defining Dictionaries

观察以下代码以了解有关定义字典:

Observe the following code to understand about defining a dictionary −

>>> # empty dictionary
>>> my_dict = {}
>>>
>>> # dictionary with integer keys
>>> my_dict = { 1:'msft', 2: 'IT'}
>>>
>>> # dictionary with mixed keys
>>> my_dict = {'name': 'Aarav', 1: [ 2, 4, 10]}
>>>
>>> # using built-in function dict()
>>> my_dict = dict({1:'msft', 2:'IT'})
>>>
>>> # From sequence having each item as a pair
>>> my_dict = dict([(1,'msft'), (2,'IT')])
>>>
>>> # Accessing elements of a dictionary
>>> my_dict[1]
'msft'
>>> my_dict[2]
'IT'
>>> my_dict['IT']
Traceback (most recent call last):
   File "<pyshell#177>", line 1, in <module>
   my_dict['IT']
KeyError: 'IT'
>>>

从上面的代码中我们可以观察到:

From the above code we can observe that:

  1. First we create a dictionary with two elements and assign it to the variable my_dict. Each element is a key-value pair, and the whole set of elements is enclosed in curly braces.

  2. The number 1 is the key and msft is its value. Similarly, 2 is the key and IT is its value.

  3. You can get values by key, but not vice-versa. Thus when we try my_dict[‘IT’] , it raises an exception, because IT is not a key.

Modifying Dictionaries

观察以下代码以了解有关修改字典:

Observe the following code to understand about modifying a dictionary −

>>> # Modifying a Dictionary
>>>
>>> my_dict
{1: 'msft', 2: 'IT'}
>>> my_dict[2] = 'Software'
>>> my_dict
{1: 'msft', 2: 'Software'}
>>>
>>> my_dict[3] = 'Microsoft Technologies'
>>> my_dict
{1: 'msft', 2: 'Software', 3: 'Microsoft Technologies'}

从上面的代码中,我们能观察到 -

From the above code we can observe that −

  1. You cannot have duplicate keys in a dictionary. Altering the value of an existing key will delete the old value.

  2. You can add new key-value pairs at any time.

  3. Dictionaries have no concept of order among elements. They are simple unordered collections.

Mixing Data types in a Dictionary

观察以下代码来了解在字典中混合数据类型 -

Observe the following code to understand about mixing data types in a dictionary −

>>> # Mixing Data Types in a Dictionary
>>>
>>> my_dict
{1: 'msft', 2: 'Software', 3: 'Microsoft Technologies'}
>>> my_dict[4] = 'Operating System'
>>> my_dict
{1: 'msft', 2: 'Software', 3: 'Microsoft Technologies', 4: 'Operating System'}
>>> my_dict['Bill Gates'] = 'Owner'
>>> my_dict
{1: 'msft', 2: 'Software', 3: 'Microsoft Technologies', 4: 'Operating System',
'Bill Gates': 'Owner'}

从上面的代码中,我们能观察到 -

From the above code we can observe that −

  1. Not just strings but dictionary value can be of any data type including strings, integers, including the dictionary itself.

  2. Unlike dictionary values, dictionary keys are more restricted, but can be of any type like strings, integers or any other.

Deleting Items from Dictionaries

观察以下代码来了解如何从字典中删除项 -

Observe the following code to understand about deleting items from a dictionary −

>>> # Deleting Items from a Dictionary
>>>
>>> my_dict
{1: 'msft', 2: 'Software', 3: 'Microsoft Technologies', 4: 'Operating System',
'Bill Gates': 'Owner'}
>>>
>>> del my_dict['Bill Gates']
>>> my_dict
{1: 'msft', 2: 'Software', 3: 'Microsoft Technologies', 4: 'Operating System'}
>>>
>>> my_dict.clear()
>>> my_dict
{}

从上面的代码中,我们能观察到 -

From the above code we can observe that −

  1. del − lets you delete individual items from a dictionary by key.

  2. clear − deletes all items from a dictionary.

Sets

集合是一种无序集合,没有重复的元素。尽管单个项不可变,但集合本身是可变的,即我们可以向集合中添加或删除元素/项。我们可以对集合执行并集、交集等数学运算。

Set() is an unordered collection with no duplicate elements. Though individual items are immutable, set itself is mutable, that is we can add or remove elements/items from the set. We can perform mathematical operations like union, intersection etc. with set.

尽管一般集合可以使用树来实现,但 Python 中的集合可以使用哈希表来实现。这允许它使用一种高度优化的方法来检查特定元素是否包含在集合中。

Though sets in general can be implemented using trees, set in Python can be implemented using a hash table. This allows it a highly optimized method for checking whether a specific element is contained in the set

Creating a set

集合是通过将所有项(元素)用逗号分隔或使用内置函数 set() 放置在花括号 {} 内创建的。观察以下代码行 -

A set is created by placing all the items (elements) inside curly braces {}, separated by comma or by using the built-in function set(). Observe the following lines of code −

>>> #set of integers
>>> my_set = {1,2,4,8}
>>> print(my_set)
{8, 1, 2, 4}
>>>
>>> #set of mixed datatypes
>>> my_set = {1.0, "Hello World!", (2, 4, 6)}
>>> print(my_set)
{1.0, (2, 4, 6), 'Hello World!'}
>>>

Methods for Sets

观察以下代码来了解集合的方法 -

Observe the following code to understand about methods for sets −

>>> >>> #METHODS FOR SETS
>>>
>>> #add(x) Method
>>> topics = {'Python', 'Java', 'C#'}
>>> topics.add('C++')
>>> topics
{'C#', 'C++', 'Java', 'Python'}
>>>
>>> #union(s) Method, returns a union of two set.
>>> topics
{'C#', 'C++', 'Java', 'Python'}
>>> team = {'Developer', 'Content Writer', 'Editor','Tester'}
>>> group = topics.union(team)
>>> group
{'Tester', 'C#', 'Python', 'Editor', 'Developer', 'C++', 'Java', 'Content
Writer'}
>>> # intersets(s) method, returns an intersection of two sets
>>> inters = topics.intersection(team)
>>> inters
set()
>>>
>>> # difference(s) Method, returns a set containing all the elements of
invoking set but not of the second set.
>>>
>>> safe = topics.difference(team)
>>> safe
{'Python', 'C++', 'Java', 'C#'}
>>>
>>> diff = topics.difference(group)
>>> diff
set()
>>> #clear() Method, Empties the whole set.
>>> group.clear()
>>> group
set()
>>>

Operators for Sets

观察以下代码来了解集合的运算符 -

Observe the following code to understand about operators for sets −

>>> # PYTHON SET OPERATIONS
>>>
>>> #Creating two sets
>>> set1 = set()
>>> set2 = set()
>>>
>>> # Adding elements to set
>>> for i in range(1,5):
   set1.add(i)
>>> for j in range(4,9):
   set2.add(j)
>>> set1
{1, 2, 3, 4}
>>> set2
{4, 5, 6, 7, 8}
>>>
>>> #Union of set1 and set2
>>> set3 = set1 | set2 # same as set1.union(set2)
>>> print('Union of set1 & set2: set3 = ', set3)
Union of set1 & set2: set3 = {1, 2, 3, 4, 5, 6, 7, 8}
>>>
>>> #Intersection of set1 & set2
>>> set4 = set1 & set2 # same as set1.intersection(set2)
>>> print('Intersection of set1 and set2: set4 = ', set4)
Intersection of set1 and set2: set4 = {4}
>>>
>>> # Checking relation between set3 and set4
>>> if set3 > set4: # set3.issuperset(set4)
   print('Set3 is superset of set4')
elif set3 < set4: #set3.issubset(set4)
   print('Set3 is subset of set4')
else: #set3 == set4
   print('Set 3 is same as set4')
Set3 is superset of set4
>>>
>>> # Difference between set3 and set4
>>> set5 = set3 - set4
>>> print('Elements in set3 and not in set4: set5 = ', set5)
Elements in set3 and not in set4: set5 = {1, 2, 3, 5, 6, 7, 8}
>>>
>>> # Check if set4 and set5 are disjoint sets
>>> if set4.isdisjoint(set5):
   print('Set4 and set5 have nothing in common\n')
Set4 and set5 have nothing in common
>>> # Removing all the values of set5
>>> set5.clear()
>>> set5 set()

Object Oriented Python - Building Blocks

在本章中,我们将详细讨论面向对象术语和编程概念。类只是实例的一个工厂。这个工厂包含描述如何创建实例的蓝图。实例或对象是根据类构造的。在大多数情况下,我们可以拥有一个类的多个实例。每个实例都有一组属性,这些属性在类中定义,因此特定类的每个实例都应具有相同的属性。

In this chapter, we will discuss object oriented terms and programming concepts in detail.Class is a just a factory for an instance. This factory contains the blueprint which describes how to make the instances. An instances or object are constructed from the class. In most cases, we can have more than one instances of a class. Every instance has a set of attribute and these attributes are defined in a class, so every instance of a particular class is expected to have the same attributes.

Class Bundles : Behavior and State

一个类可以让你将一个对象的的行为和状态捆绑在一起。观察以下图表以更好地理解 -

A class will let you bundle together the behavior and state of an object. Observe the following diagram for better understanding −

bundles

在讨论类捆绑时,以下几点值得注意 -

The following points are worth notable when discussing class bundles −

  1. The word behavior is identical to function – it is a piece of code that does something (or implements a behavior)

  2. The word state is identical to variables – it is a place to store values within a class.

  3. When we assert a class behavior and state together, it means that a class packages functions and variables.

Classes have methods and attributes

在 Python 中,创建方法定义类行为。方法这个词是面向对象编程中给类内部定义的函数的一个名称。总结一下:

In Python, creating a method defines a class behavior. The word method is the OOP name given to a function that is defined within a class. To sum up −

  1. Class functions − is synonym for methods

  2. Class variables − is synonym for name attributes.

  3. Class − a blueprint for an instance with exact behavior.

  4. Object − one of the instances of the class, perform functionality defined in the class.

  5. Type − indicates the class the instance belongs to

  6. Attribute − Any object value: object.attribute

  7. Method − a “callable attribute” defined in the class

观察以下代码段以作示例——

Observe the following piece of code for example −

var = “Hello, John”
print( type (var)) # < type ‘str’> or <class 'str'>
print(var.upper()) # upper() method is called, HELLO, JOHN

Creation and Instantiation

以下代码展示了如何创建我们的第一个类,然后创建它的实例。

The following code shows how to create our first class and then its instance.

class MyClass(object):
   pass
# Create first instance of MyClass
this_obj = MyClass()
print(this_obj)
# Another instance of MyClass
that_obj = MyClass()
print (that_obj)

在此,我们创建了一个称为 MyClass 的类,该类不做任何任务。 MyClass 类中的参数 object 涉及类继承,将在后面的章节中讨论。上面的代码中的 pass 表明,该块是空的,也就是一个空的类定义。

Here we have created a class called MyClass and which does not do any task. The argument object in MyClass class involves class inheritance and will be discussed in later chapters. pass in the above code indicates that this block is empty, that is it is an empty class definition.

让我们创建一个类 MyClass() 的实例 this_obj 并对其进行打印,如以下所示:

Let us create an instance this_obj of MyClass() class and print it as shown −

<__main__.MyClass object at 0x03B08E10>
<__main__.MyClass object at 0x0369D390>

在此,我们创建了 MyClass. 的一个实例。十六进制代码是指对象存储的地址。另一个实例指向另一个地址。

Here, we have created an instance of MyClass. The hex code refers to the address where the object is being stored. Another instance is pointing to another address.

现在让我们在类 MyClass() 中定义一个变量,并从该类的实例中获取变量,如下面的代码所示:

Now let us define one variable inside the class MyClass() and get the variable from the instance of that class as shown in the following code −

class MyClass(object):
   var = 9

# Create first instance of MyClass
this_obj = MyClass()
print(this_obj.var)

# Another instance of MyClass

that_obj = MyClass()
print (that_obj.var)

Output

执行上述代码时,可以看到以下输出:

You can observe the following output when you execute the code given above −

9
9

由于实例知道自己是通过哪个类实例化,因此当从实例请求属性时,实例会查找属性和类。这称为 attribute lookup.

As instance knows from which class it is instantiated, so when requested for an attribute from an instance, the instance looks for the attribute and the class. This is called the attribute lookup.

Instance Methods

类中定义的函数称为 method. 实例方法需要一个实例才能调用它,并且不需要装饰器。在创建实例方法时,第一个参数始终为 self. 虽然我们可以用任何其他名称调用它(self),但建议使用 self,因为它是一个命名约定。

A function defined in a class is called a method. An instance method requires an instance in order to call it and requires no decorator. When creating an instance method, the first parameter is always self. Though we can call it (self) by any other name, it is recommended to use self, as it is a naming convention.

class MyClass(object):
   var = 9
   def firstM(self):
      print("hello, World")
obj = MyClass()
print(obj.var)
obj.firstM()

Output

执行上述代码时,可以看到以下输出:

You can observe the following output when you execute the code given above −

9
hello, World

请注意,在上面的程序中,我们定义了一个方法,其中 self 为参数。但我们无法调用该方法,因为我们没有向其声明任何参数。

Note that in the above program, we defined a method with self as argument. But we cannot call the method as we have not declared any argument to it.

class MyClass(object):
   def firstM(self):
      print("hello, World")
      print(self)
obj = MyClass()
obj.firstM()
print(obj)

Output

执行上述代码时,可以看到以下输出:

You can observe the following output when you execute the code given above −

hello, World
<__main__.MyClass object at 0x036A8E10>
<__main__.MyClass object at 0x036A8E10>

Encapsulation

封装是 OOP 的基本原则之一。OOP 让我们能够隐藏对象的内部工作原理的复杂性,在以下方面对开发人员有利 −

Encapsulation is one of the fundamentals of OOP. OOP enables us to hide the complexity of the internal working of the object which is advantageous to the developer in the following ways −

  1. Simplifies and makes it easy to understand to use an object without knowing the internals.

  2. Any change can be easily manageable.

面向对象编程严重依赖于封装。术语“封装”和“抽象”(也称为数据隐藏)通常被用作同义词。它们几乎是同义词,因为抽象是通过封装实现的。

Object-oriented programming relies heavily on encapsulation. The terms encapsulation and abstraction (also called data hiding) are often used as synonyms. They are nearly synonymous, as abstraction is achieved through encapsulation.

封装为我们提供了限制对某些对象组件的访问权限的机制,这意味着对象内部表示不能从对象定义外部看到。通常通过特殊方法 GettersSetters. 来访问这些数据

Encapsulation provides us the mechanism of restricting the access to some of the object’s components, this means that the internal representation of an object can’t be seen from outside of the object definition. Access to this data is typically achieved through special methods − Getters and Setters.

这些数据存储在实例属性中,可以从类外的任何地方进行操作。为了保护它,只应使用实例方法访问该数据。禁止直接访问。

This data is stored in instance attributes and can be manipulated from anywhere outside the class. To secure it, that data should only be accessed using instance methods. Direct access should not be permitted.

class MyClass(object):
   def setAge(self, num):
      self.age = num

   def getAge(self):
      return self.age

zack = MyClass()
zack.setAge(45)
print(zack.getAge())

zack.setAge("Fourty Five")
print(zack.getAge())

Output

执行上述代码时,可以看到以下输出:

You can observe the following output when you execute the code given above −

45
Fourty Five

应该使用异常处理结构仅在数据正确有效时存储数据。如上所见,对于 setAge() 方法,没有对用户输入的限制。它可以是字符串、数字或列表。因此,我们需要检查上面的代码以确保存储的正确性。

The data should be stored only if it is correct and valid, using Exception handling constructs. As we can see above, there is no restriction on the user input to setAge() method. It could be a string, a number, or a list. So we need to check onto above code to ensure correctness of being stored.

class MyClass(object):
   def setAge(self, num):
      self.age = num

   def getAge(self):
      return self.age
zack = MyClass()
zack.setAge(45)
print(zack.getAge())
zack.setAge("Fourty Five")
print(zack.getAge())

Init Constructor

方法 *init* 会在类对象实例化后立即隐式调用。这将初始化对象。

The *init* method is implicitly called as soon as an object of a class is instantiated.This will initialize the object.

x = MyClass()

上面显示的这一行代码将创建一个新实例,并将该对象分配给局部变量 x。

The line of code shown above will create a new instance and assigns this object to the local variable x.

实例化操作,即 calling a class object ,创建一个空对象。许多类希望使用对象创建一个实例,该实例定制为特定的初始状态。因此,类可以定义一个名为 “ init ()“ 的特殊方法,如下所示 −

The instantiation operation, that is calling a class object, creates an empty object. Many classes like to create objects with instances customized to a specific initial state. Therefore, a class may define a special method named ‘ init() ‘ as shown −

def __init__(self):
   self.data = []

Python 在实例化期间调用 init ,定义了一个当类实例化时应该出现的附加属性,该属性可以设置该对象的某些起始值或在实例化时运行所需例程。因此,在此示例中,可以通过以下方法获取一个新的已初始化实例 −

Python calls init during the instantiation to define an additional attribute that should occur when a class is instantiated that may be setting up some beginning values for that object or running a routine required on instantiation. So in this example, a new, initialized instance can be obtained by −

x = MyClass()

方法 init () 可以具有一个或多个参数,来获得更大的灵活性。init 表示初始化,因为它初始化实例的属性。它被称为类的构造器。

The init() method can have single or multiple arguments for a greater flexibility. The init stands for initialization, as it initializes attributes of the instance. It is called the constructor of a class.

class myclass(object):
   def __init__(self,aaa, bbb):
      self.a = aaa
      self.b = bbb

x = myclass(4.5, 3)
print(x.a, x.b)

Output

4.5 3

Class Attributes

类中定义的属性称为“类属性”,而函数中定义的属性称为“实例属性”。在定义时,这些属性没有前缀 self,因为它们是类的属性,而不是特定实例的属性。

The attribute defined in the class is called “class attributes’ and the attributes defined in the function is called ‘instance attributes’. While defining, these attributes are not prefixed by self, as these are the property of the class and not of a particular instance.

类属性可以通过类本身( className.attributeName)以及类的实例(inst.attributeName)来访问。因此,实例既可以访问实例属性,也可以访问类属性。

The class attributes can be accessed by the class itself ( className.attributeName) as well as by the instances of the class (inst.attributeName). So, the instances have access to both the instance attribute as well as class attributes.

>>> class myclass():
   age = 21
>>> myclass.age
21
>>> x = myclass()
>>> x.age
21
>>>

类属性可以在实例中被覆盖,虽然这并不是一个打破封装的好方法。

A class attribute can be overridden in an instance, even though it is not a good method to break encapsulation.

Python 中有一个用于查找属性的路径。第一个是在类中定义的方法,然后是其上方的类。

There is a lookup path for attributes in Python. The first being the method defined within the class, and then the class above it.

>>> class myclass(object):
   classy = 'class value'
>>> dd = myclass()
>>> print (dd.classy) # This should return the string 'class value'
class value
>>>
>>> dd.classy = "Instance Value"
>>> print(dd.classy) # Return the string "Instance Value"
Instance Value
>>>
>>> # This will delete the value set for 'dd.classy' in the instance.
>>> del dd.classy
>>> >>> # Since the overriding attribute was deleted, this will print 'class
value'.

>>> print(dd.classy)
class value
>>>

我们在实例 dd 中覆盖“classy”类属性。覆盖时,Python 解释器会读取覆盖的值。但是一旦新值被“del”删除,覆盖的值便不再存在于该实例中,因此查找将向上一个级别并从类中获取它。

We are overriding the ‘classy’ class attribute in the instance dd. When it’s overridden, the Python interpreter reads the overridden value. But once the new value is deleted with ‘del’, the overridden value is no longer present in the instance, and hence the lookup goes a level above and gets it from the class.

Working with Class and Instance Data

在本节中,让我们了解类数据与实例数据的关系。我们可以将数据存储在类中或实例中。在设计类时,我们需要决定哪些数据属于实例,哪些数据应该存储在总体类中。

In this section, let us understand how the class data relates to the instance data. We can store data either in a class or in an instance. When we design a class, we decide which data belongs to the instance and which data should be stored into the overall class.

实例可以访问类数据。如果我们创建多个实例,那么这些实例既可以访问它们各自的属性值,也可以访问总体类数据。

An instance can access the class data. If we create multiple instances, then these instances can access their individual attribute values as well the overall class data.

因此,类数据是所有实例共享的数据。观察下面给出的代码以更好地理解−

Thus, a class data is the data that is shared among all the instances. Observe the code given below for better undersanding −

class InstanceCounter(object):
   count = 0 # class attribute, will be accessible to all instances
   def __init__(self, val):
      self.val = val
      InstanceCounter.count +=1 # Increment the value of class attribute, accessible through class name
# In above line, class ('InstanceCounter') act as an object
   def set_val(self, newval):
      self.val = newval

   def get_val(self):
      return self.val

   def get_count(self):
      return InstanceCounter.count
a = InstanceCounter(9)
b = InstanceCounter(18)
c = InstanceCounter(27)

for obj in (a, b, c):
   print ('val of obj: %s' %(obj.get_val())) # Initialized value ( 9, 18, 27)
   print ('count: %s' %(obj.get_count())) # always 3

Output

val of obj: 9
count: 3
val of obj: 18
count: 3
val of obj: 27
count: 3

简而言之,类属性对于类的所有实例都是相同的,而实例属性对于每个实例都是特定的。对于两个不同的实例,我们将有两种不同的实例属性。

In short, class attributes are same for all instances of class whereas instance attributes is particular for each instance. For two different instances, we will have two different instance attributes.

class myClass:
   class_attribute = 99

   def class_method(self):
      self.instance_attribute = 'I am instance attribute'

print (myClass.__dict__)

Output

执行上述代码时,可以看到以下输出:

You can observe the following output when you execute the code given above −

{'__module__': '__main__', 'class_attribute': 99, 'class_method': <function myClass.class_method at 0x04128D68>, '__dict__': <attribute '__dict__' of 'myClass' objects>, '__weakref__': <attribute '__weakref__' of 'myClass' objects>, '__doc__': None}

实例属性 myClass.dict 如下所示−

The instance attribute myClass.dict as shown −

>>> a = myClass()
>>> a.class_method()
>>> print(a.__dict__)
{'instance_attribute': 'I am instance attribute'}

Object Oriented Shortcuts

本章节详细讲述了Python中各种内建函数、文件 I/O 操作和重载概念。

This chapter talks in detail about various built-in functions in Python, file I/O operations and overloading concepts.

Python Built-in Functions

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

The Python interpreter has a number of functions called built-in functions that are readily available for use. In its latest version, Python contains 68 built-in functions as listed in the table given below −

BUILT-IN FUNCTIONS

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()

本节简要讨论了一些重要的函数 −

This section discusses some of the important functions in brief −

len() function

len() 函数获取字符串、列表或集合的长度。它返回对象的长度或项目数,其中对象可以是字符串、列表或集合。

The len() function gets the length of strings, list or collections. It returns the length or number of items of an object, where object can be a string, list or a collection.

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

len() 函数在内部像 list.len()tuple.len() 一样工作。因此,请注意,len() 仅对具有 *len ()* 方法的对象起作用。

len() function internally works like list.len() or tuple.len(). Thus, note that len() works only on objects that has a *len()* method.

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

然而,在实践中,我们偏爱 len() ,而不是 len() 函数,原因如下 −

However, in practice, we prefer len() instead of the len() function because of the following reasons −

  1. It is more efficient. And it is not necessary that a particular method is written to refuse access to special methods such as len.

  2. It is easy to maintain.

  3. It supports backward compatibility.

Reversed(seq)

返回反转迭代器。seq必须是具有 reversed ()方法,或者支持序列协议的( len ()方法和 getitem ()方法)的对象。通常在 for 循环中使用,当我们想要从后往前循环项目时。

It returns the reverse iterator. seq must be an object which has reversed() method or supports the sequence protocol (the len() method and the getitem() method). It is generally used in for loops when we want to loop over items from back to front.

>>> 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循环打印普通列表的反转列表,以及两个自定义序列的实例。输出结果表明 reversed() 适用于所有这三个序列,但是当我们定义 reversed 时,结果非常不同。

The for loop at the end prints the reversed list of a normal list, and instances of the two custom sequences. The output shows that reversed() works on all the three of them, but has a very different results when we define reversed.

Output

执行上述代码时,可以看到以下输出:

You can observe the following output when you execute the code given above −

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

Enumerate

enumerate () 方法为可迭代项添加一个计数器,然后返回数数对象。

The enumerate () method adds a counter to an iterable and returns the enumerate object.

enumerate ()的语法为−

The syntax of enumerate () is −

enumerate(iterable, start = 0)

这里,第二个参数 start 是可选的,默认情况下索引从0开始。

Here the second argument start is optional, and by default index starts with zero (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() 返回一个迭代器,它产生一个包含在传递序列中元素计数的元组。由于返回值是迭代器,因此直接访问它并没有太大的用处。使用for循环进行计数是enumerate()的一种更好方法。

So enumerate() returns an iterator which yields a tuple that keeps count of the elements in the sequence passed. Since the return value is an iterator, directly accessing it is not much useful. A better approach for enumerate() is keeping count within a for loop.

>>> 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

在标准库中还有许多其他函数,下面列出了一些更广泛使用的函数:

There are many other functions in the standard library, and here is another list of some more widely used functions −

  1. hasattr, getattr, setattr and delattr, which allows attributes of an object to be manipulated by their string names.

  2. all and any, which accept an iterable object and return True if all, or any, of the items evaluate to be true.

  3. nzip, which takes two or more sequences and returns a new sequence of tuples, where each tuple contains a single value from each sequence.

File I/O

文件概念与面向对象编程术语相关。Python 已经将操作系统在抽象中提供的接口封装起来,允许我们处理文件对象。

The concept of files is associated with the term object-oriented programming. Python has wrapped the interface that operating systems provided in abstraction that allows us to work with file objects.

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

The open() built-in function is used to open a file and return a file object. It is the most commonly used function with two arguments −

open(filename, mode)

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

The open() function calls two argument, first is the filename and second is the mode. Here mode can be ‘r’ for read only mode, ‘w’ for only writing (an existing file with the same name will be erased), and ‘a’ opens the file for appending, any data written to the file is automatically added to the end. ‘r+’ opens the file for both reading and writing. The default mode is read only.

在 Windows 中,附加到模式后的“b”以二进制模式打开文件,因此还有“rb”、“wb”和“r+b”等模式。

On windows, ‘b’ appended to the mode opens the file in binary mode, so there are also modes like ‘rb’, ‘wb’ and ‘r+b’.

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

在某些情况下,我们只想追加到现有文件,而不是覆盖它,为此,我们可以提供值“a”作为模式参数,将其追加到文件末尾,而不是完全覆盖现有文件内容。

In some cases, we just want to append to the existing file rather then over-writing it, for that we could supply the value ‘a’ as a mode argument, to append to the end of the file, rather than completely overwriting existing file contents.

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

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

Once a file is opened for reading, we can call the read, readline, or readlines method to get the contents of the file. The read method returns the entire contents of the file as a str or bytes object, depending on whether the second argument is ‘b’.

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

For readability, and to avoid reading a large file in one go, it is often better to use a for loop directly on a file object. For text files, it will read each line, one at a time, and we can process it inside the loop body. For binary files however it’s better to read fixed-sized chunks of data using the read() method, passing a parameter for the maximum number of bytes to read.

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

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

Writing to a file, through write method on file objects will writes a string (bytes for binary data) object to the file. The writelines method accepts a sequence of strings and write each of the iterated values to the file. The writelines method does not append a new line after each item in the sequence.

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

Finally the close() method should be called when we are finished reading or writing the file, to ensure any buffered writes are written to the disk, that the file has been properly cleaned up and that all resources tied with the file are released back to the operating system. It’s a better approach to call the close() method but technically this will happen automatically when the script exists.

An alternative to method overloading

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

Method overloading refers to having multiple methods with the same name that accept different sets of arguments.

给定单个方法或函数,我们可以自己指定参数的数量。根据函数定义,可以调用它,参数个数为 0、1、2 或更多。

Given a single method or function, we can specify the number of parameters ourself. Depending on the function definition, it can be called with zero, one, two or more parameters.

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')

Output

Hello
Hello Rahul

Default Arguments

Functions Are Objects Too

可调用对象是可以接受一些参数并可能返回对象的。函数是 Python 中最简单的可调用对象,但还有其他对象,如类或某些类实例。

A callable object is an object can accept some arguments and possibly will return an object. A function is the simplest callable object in Python, but there are others too like classes or certain class instances.

Python 中的每个函数都是一个对象。对象可以包含方法或函数,但对象不必是函数。

Every function in a Python is an object. Objects can contain methods or functions but object is not necessary a function.

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)

在上面的代码中,我们能够将两个不同的函数作为参数传递给我们的第三个函数,并为每个函数获取不同的输出,即:

In the above code, we are able to pass two different functions as argument into our third function, and get different Output for each one −

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

callable objects

就像函数是可以设置属性的对象一样,也可以创建一个可以像函数一样被调用的对象。

Just as functions are objects that can have attributes set on them, it is possible to create an object that can be called as though it were a function.

在 Python 中,具有 call () 方法的任何对象都可以使用函数调用语法进行调用。

In Python any object with a call() method can be called using function-call syntax.

Inheritance and Polymorphism

继承和多态性——这是 Python 中一个非常重要的概念。如果你想学习,你必须更深入地了解它。

Inheritance and polymorphism – this is a very important concept in Python. You must understand it better if you want to learn.

Inheritance

面向对象编程的主要优势之一是重用。继承就是实现这一目标的机制之一。继承允许程序员首先创建一个通用类或基类,然后稍后将其扩展为更专门的类。它允许程序员编写更好的代码。

One of the major advantages of Object Oriented Programming is re-use. Inheritance is one of the mechanisms to achieve the same. Inheritance allows programmer to create a general or a base class first and then later extend it to more specialized class. It allows programmer to write better code.

使用继承,你可以使用或继承基类中所有可用的数据字段和方法。稍后,你可以添加自己方法和数据字段,因此继承提供了一种组织代码的方法,而不是从头开始重写它。

Using inheritance you can use or inherit all the data fields and methods available in your base class. Later you can add you own methods and data fields, thus inheritance provides a way to organize code, rather than rewriting it from scratch.

在面向对象术语中,当类 X 扩展类 Y 时,Y 被称为超类/父类/基类,X 被称为子类/子类/派生类。这里需要注意的一点是只有非私有的数据字段和方法可供子类访问。私有数据字段和方法仅可在类内访问。

In object-oriented terminology when class X extend class Y, then Y is called super/parent/base class and X is called subclass/child/derived class. One point to note here is that only data fields and method which are not private are accessible by child classes. Private data fields and methods are accessible only inside the class.

创建派生类的语法为 -

syntax to create a derived class is −

class BaseClass:
   Body of base class
class DerivedClass(BaseClass):
   Body of derived class

Inheriting Attributes

现在,看下面的示例 -

Now look at the below example −

inheriting attributes

Output

inheriting attributes output

我们首先创建一个名为 Date 的类,并传递对象作为参数,这里的对象是由 Python 提供的内置类。稍后,我们创建另一个名为 time 的类,并调用 Date 类作为参数。通过此调用,我们可以访问时间类中日期类的所有数据和属性。正因为如此,当我们尝试从我们之前创建的时间类对象 tm 中获取 get_date 方法时,这是可能的。

We first created a class called Date and pass the object as an argument, here-object is built-in class provided by Python. Later we created another class called time and called the Date class as an argument. Through this call we get access to all the data and attributes of Date class into the Time class. Because of that when we try to get the get_date method from the Time class object tm we created earlier possible.

Object.Attribute Lookup Hierarchy

  1. The instance

  2. The class

  3. Any class from which this class inherits

Inheritance Examples

让我们仔细看看继承示例——

Let’s take a closure look into the inheritance example −

inheritance example

让我们创建两个类来参与示例 -

Let’s create couple of classes to participate in examples −

  1. Animal − Class simulate an animal

  2. Cat − Subclass of Animal

  3. Dog − Subclass of Animal

在 Python 中,用于创建对象(实例)并为属性分配值的是类的构造函数。

In Python, constructor of class used to create an object (instance), and assign the value for the attributes.

子类构造函数总是调用父类构造函数以初始化其属性值,然后开始为其属性分配值。

Constructor of subclasses always called to a constructor of parent class to initialize value for the attributes in the parent class, then it start assign value for its attributes.

python constructor

Output

python constructor output

在上面的示例中,我们看到在父类中放置的命令属性或方法,以便所有子类或子类都将从父类继承该属性。

In the above example, we see the command attributes or methods we put in the parent class so that all subclasses or child classes will inherits that property from the parent class.

如果子类尝试从另一个子类继承方法或数据,那么它将引发错误,就像我们看到 Dog 类试图从该 cat 类中调用 swatstring() 方法时,它会引发错误(在本例中类似 AttributeError)。

If a subclass try to inherits methods or data from another subclass then it will through an error as we see when Dog class try to call swatstring() methods from that cat class, it throws an error(like AttributeError in our case).

Polymorphism (“MANY SHAPES”)

多态性是 Python 中类定义的一项重要功能,在您跨类或子类拥有同名方法时使用。这允许函数在不同时间使用不同类型的实体。所以,它提供了灵活性并松散耦合,以便随着时间的推移可以扩展和容易维护代码。

Polymorphism is an important feature of class definition in Python that is utilized when you have commonly named methods across classes or subclasses. This permits functions to use entities of different types at different times. So, it provides flexibility and loose coupling so that code can be extended and easily maintained over time.

这允许函数使用任何这些多态类的对象,而无需了解跨类的区别。

This allows functions to use objects of any of these polymorphic classes without needing to be aware of distinctions across the classes.

多态性可以通过继承来实现,其中子类使用基类方法或重写它们。

Polymorphism can be carried out through inheritance, with subclasses making use of base class methods or overriding them.

让我们用我们之前关于继承的示例来理解多态性的概念,并在两个子类中添加一个称为 show_affection 的通用方法 −

Let understand the concept of polymorphism with our previous inheritance example and add one common method called show_affection in both subclasses −

从示例中我们可以看到,它指的是一种设计,其中不同类型对象可以以相同的方式被对待,或者更具体地说,两个或多个具有同名方法或通用接口的类,因为相同的方法(在本例中为 show_affection)被使用任一类型的对象调用。

From the example we can see, it refers to a design in which object of dissimilar type can be treated in the same manner or more specifically two or more classes with method of the same name or common interface because same method(show_affection in below example) is called with either type of objects.

polymorphism

Output

polymorphism output

因此,所有动物都会表现出感情(show_affection),但它们表现方式不同。“show_affection” 行为因此是多态的,因为它的行为因动物而异。因此,抽象的“动物”概念实际上不会“show_affection”,但特定的动物(例如狗和猫)具有动作“show_affection” 的具体实现。

So, all animals show affections (show_affection), but they do differently. The “show_affection” behaviors is thus polymorphic in the sense that it acted differently depending on the animal. So, the abstract “animal” concept does not actually “show_affection”, but specific animals(like dogs and cats) have a concrete implementation of the action “show_affection”.

Python 本身具有多态的类。例如,len() 函数可以与多个对象一起使用,并且所有函数都根据输入参数返回正确的输出。

Python itself have classes that are polymorphic. Example, the len() function can be used with multiple objects and all return the correct output based on the input parameter.

polymorphic

Overriding

在 Python 中,当一个子类包含一个覆盖超类方法的方法时,还可以通过调用来调用超类方法

In Python, when a subclass contains a method that overrides a method of the superclass, you can also call the superclass method by calling

Super(Subclass, self).method 而不是 self.method。

Super(Subclass, self).method instead of self.method.

Example

class Thought(object):
   def __init__(self):
      pass
   def message(self):
      print("Thought, always come and go")

class Advice(Thought):
   def __init__(self):
      super(Advice, self).__init__()
   def message(self):
      print('Warning: Risk is always involved when you are dealing with market!')

Inheriting the Constructor

如果从我们之前的继承示例中可以看到, init 位于父类中的向上,因为子类 dog 或 cat 没有 init 方法。Python 使用继承属性查找来在 animal 类中查找 init 。当我们创建子类时,它将首先在 dog 类中查找 init 方法,然后在未找到后查看父类 Animal 并找到它们并进行调用。因此,随着我们类设计的变得复杂,我们可能希望首先通过父类构造函数,然后通过子类构造函数来初始化一个实例。

If we see from our previous inheritance example, init was located in the parent class in the up ‘cause the child class dog or cat didn’t‘ve init method in it. Python used the inheritance attribute lookup to find init in animal class. When we created the child class, first it will look the init method in the dog class, then it didn’t find it then looked into parent class Animal and found there and called that there. So as our class design became complex we may wish to initialize a instance firstly processing it through parent class constructor and then through child class constructor.

constructor

Output

constructor output

在上例中——所有动物都有一个名称,所有狗都有一个特定的品种。我们使用 super 来调用父类构造函数。因此,dog 有它自己的 init ,但首先发生的是我们调用 super。Super 是内置函数,它旨在将一个类与其超类或其父类相关联。

In above example- all animals have a name and all dogs a particular breed. We called parent class constructor with super. So dog has its own init but the first thing that happen is we call super. Super is built in function and it is designed to relate a class to its super class or its parent class.

在这种情况下,我们所说的是获取 dog 的超类并将 dog 实例传递给我们在构造函数中所说的任何方法 init 。因此,换句话说,我们使用 dog 对象调用父类 Animal init 。你可能想知道,为什么我们不直接使用 dog 实例来说 Animal init ,我们也可以这样做,但是如果 animal 类名称在将来某个时间发生更改怎么办。如果我们想要重新排列类层次结构,那么 dog 会从另一个类继承。在这种情况下使用 super 会让事情保持模块化,并且易于更改和维护。

In this case we saying that get the super class of dog and pass the dog instance to whatever method we say here the constructor init. So in another words we are calling parent class Animal init with the dog object. You may ask why we won’t just say Animal init with the dog instance, we could do this but if the name of animal class were to change, sometime in the future. What if we wanna rearrange the class hierarchy,so the dog inherited from another class. Using super in this case allows us to keep things modular and easy to change and maintain.

因此,在这个示例中,我们能够将通用 init 功能与更具体的功能相结合。这给了我们机会将通用功能与特定功能分开,这可以消除代码重复,并且以反映系统整体设计的方式将类相互关联。

So in this example we are able to combine general init functionality with more specific functionality. This gives us opportunity to separate common functionality from the specific functionality which can eliminate code duplication and relate class to one another in a way that reflects the system overall design.

Conclusion

  1. init is like any other method; it can be inherited

  2. If a class does not have a init constructor, Python will check its parent class to see if it can find one.

  3. As soon as it finds one, Python calls it and stops looking

  4. We can use the super () function to call methods in the parent class.

  5. We may want to initialize in the parent as well as our own class.

Multiple Inheritance and the Lookup Tree

顾名思义,多重继承是 Python 中的一个类从多个类继承的情况。

As its name indicates, multiple inheritance is Python is when a class inherits from multiple classes.

例如,一个孩子从父母(母亲和父亲)双方继承性格特征。

For example, a child inherits personality traits from both parents (Mother and Father).

Python Multiple Inheritance Syntax

要让一个类从多个父类继承,我们在定义它时将这些类的名称写在派生类的圆括号中。我们用逗号分隔这些名称。

To make a class inherits from multiple parents classes, we write the the names of these classes inside the parentheses to the derived class while defining it. We separate these names with comma.

下面是一个示例:

Below is an example of that −

>>> class Mother:
   pass

>>> class Father:
   pass

>>> class Child(Mother, Father):
   pass

>>> issubclass(Child, Mother) and issubclass(Child, Father)
True

多重继承是指从两个或两个以上的类中继承的能力。当孩子从父母继承,而父母从祖父母类继承时,复杂性就会出现。Python 会爬一个继承树,寻找要从某个对象读取的属性。它将在实例中、类内、父类中和最后从祖父母类中进行检查。现在出现的一个问题是,以什么顺序搜索这些类——广度优先还是深度优先。默认情况下,Python 使用深度优先。

Multiple inheritance refers to the ability of inheriting from two or more than two class. The complexity arises as child inherits from parent and parents inherits from the grandparent class. Python climbs an inheriting tree looking for attributes that is being requested to be read from an object. It will check the in the instance, within class then parent class and lastly from the grandparent class. Now the question arises in what order the classes will be searched - breath-first or depth-first. By default, Python goes with the depth-first.

这就是为什么在下面的图表中,Python 首先在类 A 中搜索 dothis() 方法。因此,以下示例中的方法解析顺序为:

That’s is why in the below diagram the Python searches the dothis() method first in class A. So the method resolution order in the below example will be

Mro- D→B→A→C

Mro- D→B→A→C

查看下面的多重继承图表:

Look at the below multiple inheritance diagram −

multiple inheritance

让我们通过一个示例来了解 Python 的“mro”特性的。

Let’s go through an example to understand the “mro” feature of an Python.

Output

python mro feature output

Example 3

让我们再举一个“菱形”多重继承的示例。

Let’s take another example of “diamond shape” multiple inheritance.

diamond shape multiple inheritance

上面的图表将被认为是模棱两可的。从我们之前的示例中理解“方法解析顺序” .i.e. mro 将为 D→B→A→C→A,但事实并非如此。从 C 中获得第二个 A 时,Python 将忽略前面的 A。因此,在这种情况下,mro 将为 D→B→C→A。

Above diagram will be considered ambiguous. From our previous example understanding “method resolution order” .i.e. mro will be D→B→A→C→A but it’s not. On getting the second A from the C, Python will ignore the previous A. so the mro will be in this case will be D→B→C→A.

让我们基于上面的图表创建一个示例:

Let’s create an example based on above diagram −

method resolution order

Output

method resolution order output

理解以上输出的简单规则是——如果同一个类出现在方法解析顺序中,则这个类的早期出现将从方法解析顺序中移除。

Simple rule to understand the above output is- if the same class appear in the method resolution order, the earlier appearances of this class will be remove from the method resolution order.

总结:

In conclusion −

  1. Any class can inherit from multiple classes

  2. Python normally uses a “depth-first” order when searching inheriting classes.

  3. But when two classes inherit from the same class, Python eliminates the first appearances of that class from the mro.

Decorators, Static and Class Methods

函数(或方法)通过 def 语句创建。

Functions(or methods) are created by def statement.

尽管方法在以下一点上的工作方式与函数完全相同,但方法的第一个参数是实例对象。

Though methods works in exactly the same way as a function except one point where method first argument is instance object.

我们可以根据其行为方式对方法进行分类,例如:

We can classify methods based on how they behave, like

  1. Simple method − defined outside of a class. This function can access class attributes by feeding instance argument:

def outside_func(():
  1. Instance method

def func(self,)
  1. Class method − if we need to use class attributes

   @classmethod
def cfunc(cls,)
  1. Static method − do not have any info about the class

      @staticmethod
def sfoo()

到目前为止,我们已经看到了实例方法,现在是时候深入了解其他两种方法了,

Till now we have seen the instance method, now is the time to get some insight into the other two methods,

Class Method

@classmethod 装饰器是一个内置函数装饰器,它将作为第一个参数传递调用它的类,或调用它的实例的类。该评估的结果会隐藏您的函数定义。

The @classmethod decorator, is a builtin function decorator that gets passed the class it was called on or the class of the instance it was called on as first argument. The result of that evaluation shadows your function definition.

syntax

class C(object):
   @classmethod
   def fun(cls, arg1, arg2, ...):
      ....
fun: function that needs to be converted into a class method
returns: a class method for function

他们有权访问此 cls 参数,它不能修改对象实例状态。这需要访问 self。

They have the access to this cls argument, it can’t modify object instance state. That would require access to self.

  1. It is bound to the class and not the object of the class.

  2. Class methods can still modify class state that applies across all instances of the class.

Static Method

静态方法不接受 self 或 cls(class) 参数,但它可以自由地接受任意数量的其他参数。

A static method takes neither a self nor a cls(class) parameter but it’s free to accept an arbitrary number of other parameters.

syntax

syntax

class C(object):
   @staticmethod
   def fun(arg1, arg2, ...):
   ...
returns: a static method for function funself.
  1. A static method can neither modify object state nor class state.

  2. They are restricted in what data they can access.

When to use what

  1. We generally use class method to create factory methods. Factory methods return class object (similar to a constructor) for different use cases.

  2. We generally use static methods to create utility functions.

Python Design Pattern

Overview

现代软件开发需要满足复杂业务需求。它还需要考虑以下因素,例如将来的可扩展性和可维护性。软件系统的好设计对于实现这些目标至关重要。设计模式在这样的系统中起着重要作用。

Modern software development needs to address complex business requirements. It also needs to take into account factors such as future extensibility and maintainability. A good design of a software system is vital to accomplish these goals. Design patterns play an important role in such systems.

为了理解设计模式,让我们考虑以下示例 -

To understand design pattern, let’s consider below example −

  1. Every car’s design follows a basic design pattern, four wheels, steering wheel, the core drive system like accelerator-break-clutch, etc.

因此,所有反复构建/生成的物品必然在其设计中遵循一种模式,比如汽车、自行车、比萨饼、ATM 机,甚至是你的沙发床。

So, all things repeatedly built/ produced, shall inevitably follow a pattern in its design.. it cars, bicycle, pizza, atm machines, whatever…even your sofa bed.

几乎已成为编码软件中的某种逻辑/机制/技术标准的方法的设计,因此被称为或研究为软件设计模式。

Designs that have almost become standard way of coding some logic/mechanism/technique in software, hence come to be known as or studied as, Software Design Patterns.

Why is Design Pattern Important?

使用设计模式的好处如下−

Benefits of using Design Patterns are −

  1. Helps you to solve common design problems through a proven approach.

  2. No ambiguity in the understanding as they are well documented.

  3. Reduce the overall development time.

  4. Helps you deal with future extensions and modifications with more ease than otherwise.

  5. May reduce errors in the system since they are proven solutions to common problems.

Classification of Design Patterns

GoF(四人帮)设计模式分为三类,即创建型、结构型和行为型。

The GoF (Gang of Four) design patterns are classified into three categories namely creational, structural and behavioral.

Creational Patterns

创建型设计模式将对象创建逻辑与系统其他部分分离开来。创建型模式替代你创建对象,为你创建它们。创建型模式包括抽象工厂、生成器、工厂方法、原型和单例。

Creational design patterns separate the object creation logic from the rest of the system. Instead of you creating objects, creational patterns creates them for you. The creational patterns include Abstract Factory, Builder, Factory Method, Prototype and Singleton.

由于语言的动态特性,Python 中通常不使用创建型模式。此外,语言本身为我们提供了创建的所需灵活性,以足够优雅的方式,我们很少需要在顶层实现任何东西,如单例或工厂。

Creational Patterns are not commonly used in Python because of the dynamic nature of the language. Also language itself provide us with all the flexibility we need to create in a sufficient elegant fashion, we rarely need to implement anything on top, like singleton or Factory.

此外,这些模式提供了一种在隐藏创建逻辑的情况下创建对象的方式,而不是直接使用 new 运算符实例化对象。

Also these patterns provide a way to create objects while hiding the creation logic, rather than instantiating objects directly using a new operator.

Structural Patterns

有时,你不必从头开始,而是需要使用一组现有的类来构建更大的结构。这就是结构类模式使用继承来构建新结构的地方。结构对象模式使用组合/聚合来获得新功能。适配器、桥接、复合、装饰器、外观、享元和代理是结构模式。它们提供了组织类层次结构的最佳方式。

Sometimes instead of starting from scratch, you need to build larger structures by using an existing set of classes. That’s where structural class patterns use inheritance to build a new structure. Structural object patterns use composition/ aggregation to obtain a new functionality. Adapter, Bridge, Composite, Decorator, Façade, Flyweight and Proxy are Structural Patterns. They offers best ways to organize class hierarchy.

Behavioral Patterns

行为模式提供了处理对象之间通信的最佳方式。属于此类别的模式有:访问者、职责链、命令、解释器、迭代器、中介者、备忘录、观察者、状态、策略和模板方法是行为模式。

Behavioral patterns offers best ways of handling communication between objects. Patterns comes under this categories are: Visitor, Chain of responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy and Template method are Behavioral Patterns.

因为它们表示系统的行为,所以通常用于描述软件系统的功能。

Because they represent the behavior of a system, they are used generally to describe the functionality of software systems.

Commonly used Design Patterns

Singleton

它是所有设计模式中最有争议和最著名的模式之一。它用于过度面向对象语言,并且是传统面向对象编程的重要组成部分。

It is one of the most controversial and famous of all design patterns. It is used in overly object-oriented languages, and is a vital part of traditional object-oriented programming.

单例模式用于:

The Singleton pattern is used for,

  1. When logging needs to be implemented. The logger instance is shared by all the components of the system.

  2. The configuration files is using this because cache of information needs to be maintained and shared by all the various components in the system.

  3. Managing a connection to a database.

以下是 UML 图表,

Here is the UML diagram,

uml diagram
class Logger(object):
   def __new__(cls, *args, **kwargs):
      if not hasattr(cls, '_logger'):
      cls._logger = super(Logger, cls).__new__(cls, *args, **kwargs)
return cls._logger

此示例中,Logger 为单例。

In this example, Logger is a Singleton.

在调用 new 时,它会构造该类的某个新实例。当覆盖它时,我们首先检查我们的单例实例是否已创建。如果没有,我们使用超级调用创建它。因此,每当我们调用 Logger 上的构造函数时,我们始终会获得完全相同的实例。

When new is called, it normally constructs a new instance of that class. When we override it, we first check if our singleton instance has been created or not. If not, we create it using a super call. Thus, whenever we call the constructor on Logger, we always get the exact same instance.

>>>
>>> obj1 = Logger()
>>> obj2 = Logger()
>>> obj1 == obj2
True
>>>
>>> obj1
<__main__.Logger object at 0x03224090>
>>> obj2
<__main__.Logger object at 0x03224090>

Object Oriented Python - Advanced Features

在此,我们将研究 Python 提供的部分高级特性

In this we will look into some of the advanced features which Python provide

Core Syntax in our Class design

在此,我们将关注 Python 如何让我们利用我们的类中的操作符。Python 主要涉及对象和方法在对象上的调用,即使它隐藏在某种便捷的语法中时也是如此。

In this we will look onto, how Python allows us to take advantage of operators in our classes. Python is largely objects and methods call on objects and this even goes on even when its hidden by some convenient syntax.

>>> var1 = 'Hello'
>>> var2 = ' World!'
>>> var1 + var2
'Hello World!'
>>>
>>> var1.__add__(var2)
'Hello World!'
>>> num1 = 45
>>> num2 = 60
>>> num1.__add__(num2)
105
>>> var3 = ['a', 'b']
>>> var4 = ['hello', ' John']
>>> var3.__add__(var4)
['a', 'b', 'hello', ' John']

因此,如果我们需要将魔术方法 add 添加到我们自己的类,我们可以这样做吗。让我们尝试。

So if we have to add magic method add to our own classes, could we do that too. Let’s try to do that.

我们有一个名为 Sumlist 的类,它具有一个构造函数 init ,该构造函数获取一个列表作为名为 my_list 的参数。

We have a class called Sumlist which has a contructor init which takes list as an argument called my_list.

class SumList(object):
   def __init__(self, my_list):
      self.mylist = my_list
   def __add__(self, other):
     new_list = [ x + y for x, y in zip(self.mylist, other.mylist)]

     return SumList(new_list)

   def __repr__(self):
      return str(self.mylist)

aa = SumList([3,6, 9, 12, 15])

bb = SumList([100, 200, 300, 400, 500])
cc = aa + bb # aa.__add__(bb)
print(cc) # should gives us a list ([103, 206, 309, 412, 515])

Output

[103, 206, 309, 412, 515]

但有很多方法是由其他魔术方法内部管理的。以下列出部分方法,

But there are many methods which are internally managed by others magic methods. Below are some of them,

'abc' in var # var.__contains__('abc')
var == 'abc' # var.__eq__('abc')
var[1] # var.__getitem__(1)
var[1:3] # var.__getslice__(1, 3)
len(var) # var.__len__()
print(var) # var.__repr__()

Inheriting From built-in types

类还可从内置类型继承,这意味着从任何内置类型继承并利用在其中发现的所有功能。

Classes can also inherit from built-in types this means inherits from any built-in and take advantage of all the functionality found there.

在以下示例中,我们正在从字典继承,但我们正在实现它的一种方法 setitem 。在我们设置字典中的键值时,会调用此 (setitem) 方法。由于这是一个魔术方法,因此它将隐式调用。

In below example we are inheriting from dictionary but then we are implementing one of its method setitem. This (setitem) is invoked when we set key and value in the dictionary. As this is a magic method, this will be called implicitly.

class MyDict(dict):

   def __setitem__(self, key, val):
      print('setting a key and value!')
      dict.__setitem__(self, key, val)

dd = MyDict()
dd['a'] = 10
dd['b'] = 20

for key in dd.keys():
   print('{0} = {1}'.format(key, dd[key]))

Output

setting a key and value!
setting a key and value!
a = 10
b = 20

让我们扩展我们的前一个示例,以下我们调用了两个魔术方法 getitemsetitem ,在处理列表索引时会更好用。

Let’s extend our previous example, below we have called two magic methods called getitem and setitem better invoked when we deal with list index.

# Mylist inherits from 'list' object but indexes from 1 instead for 0!
class Mylist(list): # inherits from list
   def __getitem__(self, index):
      if index == 0:
         raise IndexError
      if index > 0:
         index = index - 1
         return list.__getitem__(self, index) # this method is called when

# we access a value with subscript like x[1]
   def __setitem__(self, index, value):
      if index == 0:
         raise IndexError
      if index > 0:
      index = index - 1
      list.__setitem__(self, index, value)

x = Mylist(['a', 'b', 'c']) # __init__() inherited from builtin list

print(x) # __repr__() inherited from builtin list

x.append('HELLO'); # append() inherited from builtin list

print(x[1]) # 'a' (Mylist.__getitem__ cutomizes list superclass
               # method. index is 1, but reflects 0!

print (x[4]) # 'HELLO' (index is 4 but reflects 3!

Output

['a', 'b', 'c']
a
HELLO

在上面的示例中,我们在 Mylist 中设置了一个三项列表,并隐式调用 init 方法,并且在我们打印元素 x 时,我们获得了三项列表 ([‘a’,’b’,’c’])。然后,我们将另一元素附加到该列表。稍后我们询问索引 1 和索引 4。但如果你查看输出,我们正在从 (index-1) 中获取我们所要求的元素。众所周知,列表索引从 0 开始,但这里的索引从 1 开始(这就是我们获取列表中第一个项的原因)。

In above example, we set a three item list in Mylist and implicitly init method is called and when we print the element x, we get the three item list ([‘a’,’b’,’c’]). Then we append another element to this list. Later we ask for index 1 and index 4. But if you see the output, we are getting element from the (index-1) what we have asked for. As we know list indexing start from 0 but here the indexing start from 1 (that’s why we are getting the first item of the list).

Naming Conventions

在此,我们将研究我们对变量(特别是私有变量)使用的名称以及全世界 Python 程序员使用的约定。尽管变量被指定为私有的,但 Python 中没有隐私,这是设计使然。与任何其他有据可查的语言一样,Python 也有命令和风格方面的惯例,虽然它并不强制执行它们,但会推广它们。有一个由 Guido van Rossum” the originator of Python, that describe the best practices and use of name and is called PEP8. Here is the link for this, https://www.python.org/dev/peps/pep-0008/ 编写的风格指南

In this we will look into names we’ll used for variables especially private variables and conventions used by Python programmers worldwide. Although variables are designated as private but there is not privacy in Python and this by design. Like any other well documented languages, Python has naming and style conventions that it promote although it doesn’t enforce them. There is a style guide written by “Guido van Rossum” the originator of Python, that describe the best practices and use of name and is called PEP8. Here is the link for this, https://www.python.org/dev/peps/pep-0008/

PEP 代表 Python 增强提案,是一系列文档,在 Python 社区中分发,以讨论提议的更改。例如,建议所有人,

PEP stands for Python enhancement proposal and is a series of documentation that distributed among the Python community to discuss proposed changes. For example it is recommended all,

  1. Module names − all_lower_case

  2. Class names and exception names − CamelCase

  3. Global and local names − all_lower_case

  4. Functions and method names − all_lower_case

  5. Constants − ALL_UPPER_CASE

这些只是建议,如果你愿意,可以随时更改。但由于大多数开发人员都遵循这些建议,因此你的代码的可读性可能会降低。

These are just the recommendation, you can vary if you like. But as most of the developers follows these recommendation so might me your code is less readable.

Why conform to convention?

我们可以遵循 PEP 建议,因为这允许我们获得,

We can follow the PEP recommendation we it allows us to get,

  1. More familiar to the vast majority of developers

  2. Clearer to most readers of your code.

  3. Will match style of other contributers who work on same code base.

  4. Mark of a professional software developers

  5. Everyone will accept you.

Variable Naming − ‘Public’ and ‘Private’

在 Python 中,当我们处理模块和类时,我们将一些变量或属性指定为私有。在 Python 中,不存在“私有”实例变量,除了对象内部以外,无法访问该变量。私有简单地意味着它们根本不是供代码用户使用,而是供内部使用。通常,大多数 Python 开发人员遵循一个惯例,即一个名称以下划线开头,例如。 _attrval(以下示例)应被视为 API 或任何 Python 代码的非公有部分,无论它是一个函数、一个方法还是一个数据成员。以下是我们遵循的命名约定,

In Python, when we are dealing with modules and classes, we designate some variables or attribute as private. In Python, there is no existence of “Private” instance variable which cannot be accessed except inside an object. Private simply means they are simply not intended to be used by the users of the code instead they are intended to be used internally. In general, a convention is being followed by most Python developers i.e. a name prefixed with an underscore for example. _attrval (example below) should be treated as a non-public part of the API or any Python code, whether it is a function, a method or a data member. Below is the naming convention we follow,

  1. Public attributes or variables (intended to be used by the importer of this module or user of this class) −regular_lower_case

  2. Private attributes or variables (internal use by the module or class) −_single_leading_underscore

  3. Private attributes that shouldn’t be subclassed −__double_leading_underscore

  4. Magic attributes −double_underscores(use them, don’t create them)

class GetSet(object):

   instance_count = 0 # public

   __mangled_name = 'no privacy!' # special variable

   def __init__(self, value):
      self._attrval = value # _attrval is for internal use only
      GetSet.instance_count += 1

   @property
   def var(self):
      print('Getting the "var" attribute')
      return self._attrval

   @var.setter
   def var(self, value):
      print('setting the "var" attribute')
      self._attrval = value

   @var.deleter
   def var(self):
      print('deleting the "var" attribute')
      self._attrval = None

cc = GetSet(5)
cc.var = 10 # public name
print(cc._attrval)
print(cc._GetSet__mangled_name)

Output

setting the "var" attribute
10
no privacy!

Object Oriented Python - Files and Strings

Strings

字符串是所有编程语言中最常用的数据类型。这是为什么?因为我们更能理解文本,而不是数字,所以我们在书写和交谈时使用文本和单词,同样,在编程中,我们也使用字符串。在字符串中,我们解析文本、分析文本语义并进行数据挖掘 - 所有这些数据都是人类可理解的文本。Python 中的字符串是不可变的。

Strings are the most popular data types used in every programming language. Why? Because we, understand text better than numbers, so in writing and talking we use text and words, similarly in programming too we use strings. In string we parse text, analyse text semantics, and do data mining – and all this data is human consumed text.The string in Python is immutable.

String Manipulation

在 Python 中,字符串可以用多种方式标记,对于多行字符串可以使用单引号(')、双引号(")甚至三重引号(''')。

In Python, string can be marked in multiple ways, using single quote ( ‘ ), double quote( “ ) or even triple quote ( ‘’’ ) in case of multiline strings.

>>> # String Examples
>>> a = "hello"
>>> b = ''' A Multi line string,
Simple!'''
>>> e = ('Multiple' 'strings' 'togethers')

字符串操作非常有用,在每种语言中都得到了非常广泛的使用。通常,程序员需要分解字符串并仔细检查它们。

String manipulation is very useful and very widely used in every language. Often, programmers are required to break down strings and examine them closely.

字符串可以进行迭代(逐个字符)、切片或连接。语法与列表相同。

Strings can be iterated over (character by character), sliced, or concatenated. The syntax is the same as for lists.

str 类中包含大量方法,可以使字符串操作变得更容易。dir 和 help 命令在 Python 解释器中提供了如何使用这些方法的指导。

The str class has numerous methods on it to make manipulating strings easier. The dir and help commands provides guidance in the Python interpreter how to use them.

以下是我们使用的一些常用字符串方法。

Below are some of the commonly used string methods we use.

Sr.No.

Method & Description

1

isalpha() Checks if all characters are Alphabets

2

isdigit() Checks Digit Characters

3

isdecimal() Checks decimal Characters

4

isnumeric() checks Numeric Characters

5

find() Returns the Highest Index of substrings

6

istitle() Checks for Titlecased strings

7

join() Returns a concatenated string

8

lower() returns lower cased string

9

upper() returns upper cased string

10

partion() Returns a tuple

11

bytearray() Returns array of given byte size

12

enumerate() Returns an enumerate object

13

isprintable() Checks printable character

让我们尝试运行几个字符串方法:

Let’s try to run couple of string methods,

>>> str1 = 'Hello World!'
>>> str1.startswith('h')
False
>>> str1.startswith('H')
True
>>> str1.endswith('d')
False
>>> str1.endswith('d!')
True
>>> str1.find('o')
4
>>> #Above returns the index of the first occurence of the character/substring.
>>> str1.find('lo')
3
>>> str1.upper()
'HELLO WORLD!'
>>> str1.lower()
'hello world!'
>>> str1.index('b')
Traceback (most recent call last):
   File "<pyshell#19>", line 1, in <module>
      str1.index('b')
ValueError: substring not found
>>> s = ('hello How Are You')
>>> s.split(' ')
['hello', 'How', 'Are', 'You']
>>> s1 = s.split(' ')
>>> '*'.join(s1)
'hello*How*Are*You'
>>> s.partition(' ')
('hello', ' ', 'How Are You')
>>>

String Formatting

在 Python 3.x 中,字符串的格式发生了变化,现在更合乎逻辑且更灵活。可以在格式字符串中使用 format() 方法或 % 符号(旧样式)进行格式化。

In Python 3.x formatting of strings has changed, now it more logical and is more flexible. Formatting can be done using the format() method or the % sign(old style) in format string.

字符串可以包含文字或用大括号 {} 括起来的替换字段,每个替换字段都可以包含位置参数的数字索引或关键字参数的名称。

The string can contain literal text or replacement fields delimited by braces {} and each replacement field may contains either the numeric index of a positional argument or the name of a keyword argument.

syntax

str.format(*args, **kwargs)

Basic Formatting

>>> '{} {}'.format('Example', 'One')
'Example One'
>>> '{} {}'.format('pie', '3.1415926')
'pie 3.1415926'

以下示例允许重新调整显示顺序而不更改参数。

Below example allows re-arrange the order of display without changing the arguments.

>>> '{1} {0}'.format('pie', '3.1415926')
'3.1415926 pie'

字符串填充和对齐

Padding and aligning strings

可以将值填充到特定长度。

A value can be padded to a specific length.

>>> #Padding Character, can be space or special character
>>> '{:12}'.format('PYTHON')
'PYTHON '
>>> '{:>12}'.format('PYTHON')
' PYTHON'
>>> '{:<{}s}'.format('PYTHON',12)
'PYTHON '
>>> '{:*<12}'.format('PYTHON')
'PYTHON******'
>>> '{:*^12}'.format('PYTHON')
'***PYTHON***'
>>> '{:.15}'.format('PYTHON OBJECT ORIENTED PROGRAMMING')
'PYTHON OBJECT O'
>>> #Above, truncated 15 characters from the left side of a specified string
>>> '{:.{}}'.format('PYTHON OBJECT ORIENTED',15)
'PYTHON OBJECT O'
>>> #Named Placeholders
>>> data = {'Name':'Raghu', 'Place':'Bangalore'}
>>> '{Name} {Place}'.format(**data)
'Raghu Bangalore'
>>> #Datetime
>>> from datetime import datetime
>>> '{:%Y/%m/%d.%H:%M}'.format(datetime(2018,3,26,9,57))
'2018/03/26.09:57'

Strings are Unicode

字符串作为不可变 Unicode 字符的集合。Unicode 字符串提供了创建可在任何地方运行的软件或程序的机会,因为 Unicode 字符串可以表示任何可能的字符,而不仅仅是 ASCII 字符。

Strings as collections of immutable Unicode characters. Unicode strings provide an opportunity to create software or programs that works everywhere because the Unicode strings can represent any possible character not just the ASCII characters.

即使字节对象引用文本数据,许多 IO 操作也只知道如何处理字节。因此,了解如何在字节和 Unicode 之间进行互换非常重要。

Many IO operations only know how to deal with bytes, even if the bytes object refers to textual data. It is therefore very important to know how to interchange between bytes and Unicode.

Converting text to bytes

Converting text to bytes

将字符串转换为字节对象称为编码。有许多形式的编码,最常见的是:PNG;JPEG、MP3、WAV、ASCII、UTF-8 等。此外,(编码)是一种以字节表示音频、图像、文本等的格式。

Converting a strings to byte object is termed as encoding. There are numerous forms of encoding, most common ones are: PNG; JPEG, MP3, WAV, ASCII, UTF-8 etc. Also this(encoding) is a format to represent audio, images, text, etc. in bytes.

这种转换可以通过 encode() 实现。它将编码技术作为参数。默认情况下,我们使用“UTF-8”技术。

This conversion is possible through encode(). It take encoding technique as argument. By default, we use ‘UTF-8’ technique.

>>> # Python Code to demonstrate string encoding
>>>
>>> # Initialising a String
>>> x = 'TutorialsPoint'
>>>
>>> #Initialising a byte object
>>> y = b'TutorialsPoint'
>>>
>>> # Using encode() to encode the String >>> # encoded version of x is stored in z using ASCII mapping
>>> z = x.encode('ASCII')
>>>
>>> # Check if x is converted to bytes or not
>>>
>>> if(z==y):
   print('Encoding Successful!')
else:
   print('Encoding Unsuccessful!')
Encoding Successful!

Converting bytes to text

Converting bytes to text

将字节转换为文本称为解码。这是通过 decode() 实现的。如果我们知道哪个编码用于对其进行编码,则可以将字节字符串转换为字符字符串。

Converting bytes to text is called the decoding. This is implemented through decode(). We can convert a byte string to a character string if we know which encoding is used to encode it.

因此,编码和解码是逆向过程。

So Encoding and decoding are inverse processes.

>>>
>>> # Python code to demonstrate Byte Decoding
>>>
>>> #Initialise a String
>>> x = 'TutorialsPoint'
>>>
>>> #Initialising a byte object
>>> y = b'TutorialsPoint'
>>>
>>> #using decode() to decode the Byte object
>>> # decoded version of y is stored in z using ASCII mapping
>>> z = y.decode('ASCII')
>>> #Check if y is converted to String or not
>>> if (z == x):
   print('Decoding Successful!')
else:
   print('Decoding Unsuccessful!') Decoding Successful!
>>>

File I/O

操作系统将文件表示为字节序列,而不是文本。

Operating systems represents files as a sequence of bytes, not text.

文件是磁盘上的一个已命名位置,用于存储相关信息。它用于永久存储磁盘中的数据。

A file is a named location on disk to store related information. It is used to permanently store data in your disk.

在 Python 中,文件操作按以下顺序进行。

In Python, a file operation takes place in the following order.

  1. Open a file

  2. Read or write onto a file (operation).Open a file

  3. Close the file.

Python 用适当的解码(或编码)调用包装传入(或传出)字节流,以便我们可以直接处理 str 对象。

Python wraps the incoming (or outgoing) stream of bytes with appropriate decode (or encode) calls so we can deal directly with str objects.

Opening a file

Python 有一个内置函数 open() 来打开文件。这将生成一个文件对象,也称为句柄,因为它用于相应地读取或修改文件。

Python has a built-in function open() to open a file. This will generate a file object, also called a handle as it is used to read or modify the file accordingly.

>>> f = open(r'c:\users\rajesh\Desktop\index.webm','rb')
>>> f
<_io.BufferedReader name='c:\\users\\rajesh\\Desktop\\index.webm'>
>>> f.mode
'rb'
>>> f.name
'c:\\users\\rajesh\\Desktop\\index.webm'

要从文件中读取文本,我们只需要将文件名传递给函数。系统将打开该文件以进行读取,并使用平台默认编码将字节转换为文本。

For reading text from a file, we only need to pass the filename into the function. The file will be opened for reading, and the bytes will be converted to text using the platform default encoding.

Exception and Exception Classes

一般而言,异常是任何不寻常状况。异常通常表示错误,但有时候在程序中故意加入异常,如提早终止程序或从资源不足中回复。有许多内置的异常,表示各种状况,如读到档案结尾后,或除以零。我们可以定义我们自己的异常,称为自定义异常。

In general, an exception is any unusual condition. Exception usually indicates errors but sometimes they intentionally puts in the program, in cases like terminating a procedure early or recovering from a resource shortage. There are number of built-in exceptions, which indicate conditions like reading past the end of a file, or dividing by zero. We can define our own exceptions called custom exception.

异常处理让你能优雅地处理错误,并采取有意义的作为。异常处理有两种组件:“抛出”和“捕获”。

Exception handling enables you handle errors gracefully and do something meaningful about it. Exception handling has two components: “throwing” and ‘catching’.

Identifying Exception (Errors)

Python 中发生的每个错误都会产生异常,该异常将以其错误类型识别为错误状况。

Every error occurs in Python result an exception which will an error condition identified by its error type.

>>> #Exception
>>> 1/0
Traceback (most recent call last):
   File "<pyshell#2>", line 1, in <module>
      1/0
ZeroDivisionError: division by zero
>>>
>>> var = 20
>>> print(ver)
Traceback (most recent call last):
   File "<pyshell#5>", line 1, in <module>
      print(ver)
NameError: name 'ver' is not defined
>>> #Above as we have misspelled a variable name so we get an NameError.
>>>
>>> print('hello)

SyntaxError: EOL while scanning string literal
>>> #Above we have not closed the quote in a string, so we get SyntaxError.
>>>
>>> #Below we are asking for a key, that doen't exists.
>>> mydict = {}
>>> mydict['x']
Traceback (most recent call last):
   File "<pyshell#15>", line 1, in <module>
      mydict['x']
KeyError: 'x'
>>> #Above keyError
>>>
>>> #Below asking for a index that didn't exist in a list.
>>> mylist = [1,2,3,4]
>>> mylist[5]
Traceback (most recent call last):
   File "<pyshell#20>", line 1, in <module>
      mylist[5]
IndexError: list index out of range
>>> #Above, index out of range, raised IndexError.

Catching/Trapping Exception

当你的程序中发生不寻常的事,而且你希望使用异常机制来处理它,你就要“抛出一个异常”。关键字 try 和 except 用于捕获异常。任何时候在 try 块中发生异常时,Python 会寻找匹配的 except 块来处理该异常。如果有的话,执行就会跳到那里。

When something unusual occurs in your program and you wish to handle it using the exception mechanism, you ‘throw an exception’. The keywords try and except are used to catch exceptions. Whenever an error occurs within a try block, Python looks for a matching except block to handle it. If there is one, execution jumps there.

syntax

try:
   #write some code
   #that might throw some exception
except <ExceptionType>:
   # Exception handler, alert the user

try 子句中的代码将逐语句执行。

The code within the try clause will be executed statement by statement.

如果发生异常,try 块的其余部分将被跳过,并且 except 子句将被执行。

If an exception occurs, the rest of the try block will be skipped and the except clause will be executed.

try:
   some statement here
except:
   exception handling

让我们写一些代码,看看在你不在程序中使用任何错误处理机制时会发生什么。

Let’s write some code to see what happens when you not use any error handling mechanism in your program.

number = int(input('Please enter the number between 1 & 10: '))
print('You have entered number',number)

只要使用者输入数字,以上程序就会正常运作,但如果使用者试图输入一些其他数据类型(例如字符串或列表)时,会发生什么情况?

Above programme will work correctly as long as the user enters a number, but what happens if the users try to puts some other data type(like a string or a list).

Please enter the number between 1 > 10: 'Hi'
Traceback (most recent call last):
   File "C:/Python/Python361/exception2.py", line 1, in <module>
      number = int(input('Please enter the number between 1 & 10: '))
ValueError: invalid literal for int() with base 10: "'Hi'"

现在 ValueError 是异常类型。让我们尝试使用异常处理来重新编写上述代码。

Now ValueError is an exception type. Let’s try to rewrite the above code with exception handling.

import sys

print('Previous code with exception handling')

try:
   number = int(input('Enter number between 1 > 10: '))

except(ValueError):
   print('Error..numbers only')
   sys.exit()

print('You have entered number: ',number)

如果我们运行此程序,并且输入一个字符串(而不是数字),我们便可以看到会得到不同的结果。

If we run the program, and enter a string (instead of a number), we can see that we get a different result.

Previous code with exception handling
Enter number between 1 > 10: 'Hi'
Error..numbers only

Raising Exceptions

要从你自己的方法引发错误,你需要使用 raise 关键字,如下所示

To raise your exceptions from your own methods you need to use raise keyword like this

raise ExceptionClass(‘Some Text Here’)

我们举个例子

Let’s take an example

def enterAge(age):
   if age<0:
      raise ValueError('Only positive integers are allowed')
   if age % 2 ==0:
      print('Entered Age is even')
   else:
      print('Entered Age is odd')

try:
   num = int(input('Enter your age: '))
   enterAge(num)
except ValueError:
   print('Only positive integers are allowed')

运行程序并输入正整数。

Run the program and enter positive integer.

Expected Output

Enter your age: 12
Entered Age is even

但是当我们尝试输入负数时,会得到,

But when we try to enter a negative number we get,

Expected Output

Enter your age: -2
Only positive integers are allowed

Creating Custom exception class

你可以通过扩展 BaseException 类或 BaseException 的子类来创建自定义异常类。

You can create a custom exception class by Extending BaseException class or subclass of BaseException.

custom exception class

从上图中,我们可以看到 Python 中大多数异常类都从 BaseException 类扩展而来。你可以从 BaseException 类或其子类派生你自己的异常类。

From above diagram we can see most of the exception classes in Python extends from the BaseException class. You can derive your own exception class from BaseException class or from its subclass.

创建一个名为 NegativeNumberException.py 的新文件,并编写以下代码。

Create a new file called NegativeNumberException.py and write the following code.

class NegativeNumberException(RuntimeError):
   def __init__(self, age):
      super().__init__()
      self.age = age

以上代码创建一个新异常类,名为 NegativeNumberException,它仅包含一个构造函数,该构造函数使用 super() init () 调用父类构造函数并设置年龄。

Above code creates a new exception class named NegativeNumberException, which consists of only constructor which call parent class constructor using super()init() and sets the age.

现在为了创建你自己的自定异常类,将会编写一些代码并导入新的异常类。

Now to create your own custom exception class, will write some code and import the new exception class.

from NegativeNumberException import NegativeNumberException
def enterage(age):
   if age < 0:
      raise NegativeNumberException('Only positive integers are allowed')

   if age % 2 == 0:
      print('Age is Even')

   else:
      print('Age is Odd')

try:
   num = int(input('Enter your age: '))
   enterage(num)
except NegativeNumberException:
   print('Only positive integers are allowed')
except:
   print('Something is wrong')

Output

Enter your age: -2
Only positive integers are allowed

另一种创建自定异常类的方式。

Another way to create a custom Exception class.

class customException(Exception):
   def __init__(self, value):
      self.parameter = value

   def __str__(self):
      return repr(self.parameter)
try:
   raise customException('My Useful Error Message!')
except customException as instance:
   print('Caught: ' + instance.parameter)

Output

Caught: My Useful Error Message!

Exception hierarchy

内建异常的类层次为 −

The class hierarchy for built-in exceptions is −

+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
| +-- RecursionError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning

Object Oriented Python - Object Serialization

在数据存储的上下文中,序列化是将数据结构或对象状态转换为可以存储(例如,在文件或内存缓冲区中)或以后传输和重建的格式的过程。

In the context of data storage, serialization is the process of translating data structures or object state into a format that can be stored (for example, in a file or memory buffer) or transmitted and reconstructed later.

在序列化中,对象被转换成可以存储的格式,以便能够在以后对其进行反序列化并从序列化格式重新创建原始对象。

In serialization, an object is transformed into a format that can be stored, so as to be able to deserialize it later and recreate the original object from the serialized format.

Pickle

Pickling 是将 Python 对象层次结构转换为字节流(通常不可读)以写入文件的过程,这也称为序列化。反序列化是逆向操作,其中字节流被转换回正在工作的 Python 对象层次结构。

Pickling is the process whereby a Python object hierarchy is converted into a byte stream (usually not human readable) to be written to a file, this is also known as Serialization. Unpickling is the reverse operation, whereby a byte stream is converted back into a working Python object hierarchy.

Pickle 是存储对象的运维最简单的方式。Python Pickle 模块是一种面向对象的方式,可以将对象直接存储在特殊的存储格式中。

Pickle is operationally simplest way to store the object. The Python Pickle module is an object-oriented way to store objects directly in a special storage format.

What can it do?

  1. Pickle can store and reproduce dictionaries and lists very easily.

  2. Stores object attributes and restores them back to the same State.

What pickle can’t do?

  1. It does not save an objects code. Only it’s attributes values.

  2. It cannot store file handles or connection sockets.

简言之,我们可以说,腌制是一种将数据变量存储到文件中并从中检索数据变量的方法,其中变量可以是列表、类等。

In short we can say, pickling is a way to store and retrieve data variables into and out from files where variables can be lists, classes, etc.

要腌制某些内容,您必须:

To Pickle something you must −

  1. import pickle

  2. Write a variable to file, something like

pickle.dump(mystring, outfile, protocol),

第三个参数协议是可选的。要解腌制某些内容,您必须:

where 3rd argument protocol is optional To unpickling something you must −

导入pickle

Import pickle

将变量写入文件,类似于

Write a variable to a file, something like

myString = pickle.load(inputfile)

Methods

pickle 接口提供了四种不同的方法。

The pickle interface provides four different methods.

  1. dump() − The dump() method serializes to an open file (file-like object).

  2. dumps() − Serializes to a string

  3. load() − Deserializes from an open-like object.

  4. loads() − Deserializes from a string.

基于以上程序,以下是“腌制”的一个示例。

Based on above procedure, below is an example of “pickling”.

pickling

Output

My Cat pussy is White and has 4 legs
Would you like to see her pickled? Here she is!
b'\x80\x03c__main__\nCat\nq\x00)\x81q\x01}q\x02(X\x0e\x00\x00\x00number_of_legsq\x03K\x04X\x05\x00\x00\x00colorq\x04X\x05\x00\x00\x00Whiteq\x05ub.'

因此,在上面的示例中,我们已经创建了Cat类的实例,然后我们将其腌制,将我们的“Cat”实例转换为简单的字节数组。

So, in the example above, we have created an instance of a Cat class and then we’ve pickled it, transforming our “Cat” instance into a simple array of bytes.

通过这种方式,我们可以轻松地将字节数组存储在二进制文件或数据库字段中,并稍后从存储支持中将其还原为其原始形式。

This way we can easily store the bytes array on a binary file or in a database field and restore it back to its original form from our storage support in a later time.

另外,如果您想使用腌制对象创建一个文件,您可以使用dump()方法(而不是dumps*()*)同时传递已打开的二进制文件,并且腌制结果将自动存储在文件中。

Also if you want to create a file with a pickled object, you can use the dump() method ( instead of the dumps*()* one) passing also an opened binary file and the pickling result will be stored in the file automatically.

[….]
binary_file = open(my_pickled_Pussy.bin', mode='wb')
my_pickled_Pussy = pickle.dump(Pussy, binary_file)
binary_file.close()

Unpickling

将二进制数组转换为对象层次的过程称为解腌制。

The process that takes a binary array and converts it to an object hierarchy is called unpickling.

解腌制过程是通过使用pickle模块的load()函数完成的,并从简单的字节数组中返回一个完整对象层次。

The unpickling process is done by using the load() function of the pickle module and returns a complete object hierarchy from a simple bytes array.

让我们在前面的示例中使用load函数。

Let’s use the load function in our previous example.

unpicking

Output

MeOw is black
Pussy is white

JSON

JSON(JavaScript Object Notation)是 Python 标准库的一部分,是一种轻量级数据交换格式。它易于人类阅读和编写。它易于解析和生成。

JSON(JavaScript Object Notation) has been part of the Python standard library is a lightweight data-interchange format. It is easy for humans to read and write. It is easy to parse and generate.

由于其简单性,JSON 是一种我们存储和交换数据的方式,这是通过其 JSON 语法完成的,且用于许多 Web 应用程序中。因为它采用人类可读的格式,加上它在处理 API 时非常有效,这可能成为使用它进行数据传输的原因之一。

Because of its simplicity, JSON is a way by which we store and exchange data, which is accomplished through its JSON syntax, and is used in many web applications. As it is in human readable format, and this may be one of the reasons for using it in data transmission, in addition to its effectiveness when working with APIs.

JSON 格式数据的示例如下:

An example of JSON-formatted data is as follow −

{"EmployID": 40203, "Name": "Zack", "Age":54, "isEmployed": True}

Python 便于处理 Json 文件。为此目的而使用的模块是 JSON 模块。应将此模块包含(内置)在您的 Python 安装中。

Python makes it simple to work with Json files. The module sused for this purpose is the JSON module. This module should be included (built-in) within your Python installation.

因此,让我们看看如何将 Python 字典转换为 JSON,并将其写入文本文件。

So let’s see how can we convert Python dictionary to JSON and write it to a text file.

JSON to Python

读取 JSON 意味着将 JSON 转换为 Python 值(对象)。json 库将 JSON 解析为 Python 中的字典或列表。为此,我们使用 loads() 函数(从字符串加载),如下所示:

Reading JSON means converting JSON into a Python value (object). The json library parses JSON into a dictionary or list in Python. In order to do that, we use the loads() function (load from a string), as follow −

json to python

Output

json to python output

下面是示例 json 文件之一:

Below is one sample json file,

data1.json
{"menu": {
   "id": "file",
   "value": "File",
   "popup": {
      "menuitem": [
         {"value": "New", "onclick": "CreateNewDoc()"},
         {"value": "Open", "onclick": "OpenDoc()"},
         {"value": "Close", "onclick": "CloseDoc()"}
      ]
   }
}}

上面的内容(Data1.json)看起来像传统字典。我们可以使用 pickle 存储此文件,但其输出不是人类可读的格式。

Above content (Data1.json) looks like a conventional dictionary. We can use pickle to store this file but the output of it is not human readable form.

JSON(JavaScript 对象通知)是一种非常简单的格式,这也是它流行的原因之一。现在让我们通过下面的程序来了解 json 输出。

JSON(Java Script Object Notification) is a very simple format and that’s one of the reason for its popularity. Now let’s look into json output through below program.

java script object notification

Output

java script object notification output

以上我们打开了 json 文件(data1.json)进行读取,获取文件处理程序并传递到 json.load 中,然后取回对象。当我们尝试打印对象的输出时,它和 json 文件相同。尽管对象的类型是字典,但它显示为 Python 对象。正如我们看到这个 pickle 一样,写入 json 也很简单。上面我们加载了 json 文件,添加了另一个键值对,并将其写回同一个 json 文件。现在,如果我们查看 data1.json,它看起来是不同的,即它与我们之前看到的格式不同。

Above we open the json file (data1.json) for reading, obtain the file handler and pass on to json.load and getting back the object. When we try to print the output of the object, its same as the json file. Although the type of the object is dictionary, it comes out as a Python object. Writing to the json is simple as we saw this pickle. Above we load the json file, add another key value pair and writing it back to the same json file. Now if we see out data1.json, it looks different .i.e. not in the same format as we see previously.

若要使我们的输出看起来相同(人类可读的格式),请将几个参数添加到程序的最后一行,

To make our Output looks same (human readable format), add the couple of arguments into our last line of the program,

json.dump(conf, fh, indent = 4, separators = (‘,’, ‘: ‘))

与 pickle 类似,我们可以使用 dumps 打印字符串,并使用 loads 加载。以下是示例:

Similarly like pickle, we can print the string with dumps and load with loads. Below is an example of that,

string with dumps

YAML

YAML 可能是所有人编程语言中最接近于人类的 data 序列化标准。

YAML may be the most human friendly data serialization standard for all programming languages.

Python yaml 模块称为 pyaml

Python yaml module is called pyaml

YAML 是 JSON 的替代品:

YAML is an alternative to JSON −

  1. Human readable code − YAML is the most human readable format so much so that even its front-page content is displayed in YAML to make this point.

  2. Compact code − In YAML we use whitespace indentation to denote structure not brackets.

  3. Syntax for relational data − For internal references we use anchors (&) and aliases (*).

  4. One of the area where it is used widely is for viewing/editing of data structures − for example configuration files, dumping during debugging and document headers.

Installing YAML

由于 yaml 不是内置模块,因此我们需手动安装它。在 Windows 计算机上安装 yaml 的最佳方法是通过 pip。在 Windows terminal 上运行以下命令来安装 yaml:

As yaml is not a built-in module, we need to install it manually. Best way to install yaml on windows machine is through pip. Run below command on your windows terminal to install yaml,

pip install pyaml (Windows machine)
sudo pip install pyaml (*nix and Mac)

运行上方命令后,屏幕基于当前最新版本显示以下内容。

On running above command, screen will display something like below based on what’s the current latest version.

Collecting pyaml
Using cached pyaml-17.12.1-py2.py3-none-any.whl
Collecting PyYAML (from pyaml)
Using cached PyYAML-3.12.tar.gz
Installing collected packages: PyYAML, pyaml
Running setup.py install for PyYAML ... done
Successfully installed PyYAML-3.12 pyaml-17.12.1

为了测试它,在 Python shell 中导入 yaml 模块,如果未找到错误,那么我们可以说,安装成功了。

To test it, go to the Python shell and import the yaml module, import yaml, if no error is found, then we can say installation is successful.

安装 pyaml 之后,我们看一下下面的代码,

After installing pyaml, let’s look at below code,

script_yaml1.py
yaml

上面,我们创建了三个不同的数据结构、字典、列表和元组。在每个结构上,我们执行 yaml.dump。重点是如何在屏幕上显示输出。

Above we created three different data structure, dictionary, list and tuple. On each of the structure, we do yaml.dump. Important point is how the output is displayed on the screen.

Output

yaml output

字典输出看起来很干净,即 key:value。

Dictionary output looks clean .ie. key: value.

用空白分隔不同的对象。

White space to separate different objects.

列表用破折号 (-) 表示。

List is notated with dash (-)

元组首先用 !!Python/tuple 表示,然后用与列表相同格式表示。

Tuple is indicated first with !!Python/tuple and then in the same format as lists.

加载 yaml 文件

Loading a yaml file

假设我有一个 yaml 文件,其中包含,

So let’s say I have one yaml file, which contains,

---
# An employee record
name: Raagvendra Joshi
job: Developer
skill: Oracle
employed: True
foods:
   - Apple
   - Orange
   - Strawberry
   - Mango
languages:
   Oracle: Elite
   power_builder: Elite
   Full Stack Developer: Lame
education:
   4 GCSEs
   3 A-Levels
   MCA in something called com

现在,让我们编写代码来通过 yaml.load 函数加载此 yaml 文件。以下是代码。

Now let’s write a code to load this yaml file through yaml.load function. Below is code for the same.

yaml load function

由于输出看起来不是很好读,我在最后使用 json 对它进行了美化。比较我们获得的输出和我们拥有的实际 yaml 文件。

As the output doesn’t looks that much readable, I prettify it by using json in the end. Compare the output we got and the actual yaml file we have.

Output

yaml load function output

软件开发生命中最重要的一方面就是调试。在本节中,我们将了解通过内置调试器或第三方调试器进行 Python 调试的不同方式。

One of the most important aspect of software development is debugging. In this section we’ll see different ways of Python debugging either with built-in debugger or third party debuggers.

PDB – The Python Debugger

模块 PDB 支持设置断点。断点是程序有意暂停的地方,您可以在其中获得更多有关程序状态的信息。

The module PDB supports setting breakpoints. A breakpoint is an intentional pause of the program, where you can get more information about the programs state.

要设置断点,请插入以下行

To set a breakpoint, insert the line

pdb.set_trace()

Example

pdb_example1.py
import pdb
x = 9
y = 7
pdb.set_trace()
total = x + y
pdb.set_trace()

我们在本程序中插入了一些断点。程序在每个断点(pdb.set_trace())处暂停。要查看变量内容,只需键入变量名即可。

We have inserted a few breakpoints in this program. The program will pause at each breakpoint (pdb.set_trace()). To view a variables contents simply type the variable name.

c:\Python\Python361>Python pdb_example1.py
> c:\Python\Python361\pdb_example1.py(8)<module>()
-> total = x + y
(Pdb) x
9
(Pdb) y
7
(Pdb) total
*** NameError: name 'total' is not defined
(Pdb)

按 c 或继续继续执行程序,直到下一个断点。

Press c or continue to go on with the programs execution until the next breakpoint.

(Pdb) c
--Return--
> c:\Python\Python361\pdb_example1.py(8)<module>()->None
-> total = x + y
(Pdb) total
16

最终,您将需要调试更大的程序—使用子例程的程序。有时,您要查找的问题存在于子例程内。考虑以下程序。

Eventually, you will need to debug much bigger programs – programs that use subroutines. And sometimes, the problem that you’re trying to find will lie inside a subroutine. Consider the following program.

import pdb
def squar(x, y):
   out_squared = x^2 + y^2
   return out_squared
if __name__ == "__main__":
   #pdb.set_trace()
   print (squar(4, 5))

现在运行上述程序,

Now on running the above program,

c:\Python\Python361>Python pdb_example2.py
> c:\Python\Python361\pdb_example2.py(10)<module>()
-> print (squar(4, 5))
(Pdb)

我们可以使用 ? 寻求帮助,但箭头指示即将执行的行。在这个时候,点击 s s 很管用,可以逐步进入该行。

We can use ? to get help, but the arrow indicates the line that’s about to be executed. At this point it’s helpful to hit s to s to step into that line.

(Pdb) s
--Call--
>c:\Python\Python361\pdb_example2.py(3)squar()
-> def squar(x, y):

这是对函数的调用。如果您想要了解您所处代码位置的概览,请尝试 l −

This is a call to a function. If you want an overview of where you are in your code, try l −

(Pdb) l
1 import pdb
2
3 def squar(x, y):
4 -> out_squared = x^2 + y^2
5
6 return out_squared
7
8 if __name__ == "__main__":
9 pdb.set_trace()
10 print (squar(4, 5))
[EOF]
(Pdb)

您可以点击 n 跳到下一行。此时,您处于 out_squared 方法中,并且可以访问函数内部声明的变量,例如 x 和 y。

You can hit n to advance to the next line. At this point you are inside the out_squared method and you have access to the variable declared inside the function .i.e. x and y.

(Pdb) x
4
(Pdb) y
5
(Pdb) x^2
6
(Pdb) y^2
7
(Pdb) x**2
16
(Pdb) y**2
25
(Pdb)

所以我们可以看到 ^ 运算符不是我们想要的,而我们需要使用 ** 运算符来进行平方。

So we can see the ^ operator is not what we wanted instead we need to use ** operator to do squares.

通过这种方式,我们可以在函数/方法内部调试我们的程序。

This way we can debug our program inside the functions/methods.

Logging

自 Python 2.3 版本以来,logging 模块就已成为 Python 标准库的一部分。由于它是一个内置模块,所有 Python 模块都可以参与日志记录,以便我们的应用程序日志可以包含您自己的消息,以及来自第三方模块的消息。它提供了大量的灵活性与功能。

The logging module has been a part of Python’s Standard Library since Python version 2.3. As it’s a built-in module all Python module can participate in logging, so that our application log can include your own message integrated with messages from third party module. It provides a lot of flexibility and functionality.

Benefits of Logging

  1. Diagnostic logging − It records events related to the application’s operation.

  2. Audit logging − It records events for business analysis.

消息以“严重性”级别进行编写和记录。

Messages are written and logged at levels of “severity” &minu

  1. DEBUG (debug()) − diagnostic messages for development.

  2. INFO (info()) − standard “progress” messages.

  3. WARNING (warning()) − detected a non-serious issue.

  4. ERROR (error()) − encountered an error, possibly serious.

  5. CRITICAL (critical()) − usually a fatal error (program stops).

我们来看一下下面的简单程序,

Let’s looks into below simple program,

import logging

logging.basicConfig(level=logging.INFO)

logging.debug('this message will be ignored') # This will not print
logging.info('This should be logged') # it'll print
logging.warning('And this, too') # It'll print

上面我们正在记录严重性级别的消息。首先,我们导入该模块,调用 basicConfig 并设置日志记录级别。我们在上面设置的级别为 INFO。然后,我们有三个不同的语句:debug 语句、info 语句和 warning 语句。

Above we are logging messages on severity level. First we import the module, call basicConfig and set the logging level. Level we set above is INFO. Then we have three different statement: debug statement, info statement and a warning statement.

Output of logging1.py

INFO:root:This should be logged
WARNING:root:And this, too

由于 info 语句在 debug 语句之后,我们无法看到 debug 消息。要也在输出终端中获取 debug 语句,我们需要更改的只是 basicConfig 的级别。

As the info statement is below debug statement, we are not able to see the debug message. To get the debug statement too in the Output terminal, all we need to change is the basicConfig level.

logging.basicConfig(level = logging.DEBUG)

然后,我们在输出中可以看到,

And in the Output we can see,

DEBUG:root:this message will be ignored
INFO:root:This should be logged
WARNING:root:And this, too

另外,默认行为表示,如果我们未设置任何日志记录级别,则为 warning。只需注释掉上述程序的第二行并运行该代码即可。

Also the default behavior means if we don’t set any logging level is warning. Just comment out the second line from the above program and run the code.

#logging.basicConfig(level = logging.DEBUG)

Output

WARNING:root:And this, too

Python内置日志级别实际上是整数。

Python built in logging level are actually integers.

>>> import logging
>>>
>>> logging.DEBUG
10
>>> logging.CRITICAL
50
>>> logging.WARNING
30
>>> logging.INFO
20
>>> logging.ERROR
40
>>>

我们也可以将日志消息保存到文件里。

We can also save the log messages into the file.

logging.basicConfig(level = logging.DEBUG, filename = 'logging.log')

现在,所有日志消息都将进入当前工作目录中的文件(logging.log),而不是屏幕上。这是一个更好的方法,因为它让我们对得到的消息进行后期分析。

Now all log messages will go the file (logging.log) in your current working directory instead of the screen. This is a much better approach as it lets us to do post analysis of the messages we got.

我们还可以用日志消息设置日期戳。

We can also set the date stamp with our log message.

logging.basicConfig(level=logging.DEBUG, format = '%(asctime)s %(levelname)s:%(message)s')

输出将类似于,

Output will get something like,

2018-03-08 19:30:00,066 DEBUG:this message will be ignored
2018-03-08 19:30:00,176 INFO:This should be logged
2018-03-08 19:30:00,201 WARNING:And this, too

Benchmarking

基准测试或分析基本上是测试你的代码执行的速度有多快,以及瓶颈在哪里?这样做的主要原因是进行优化。

Benchmarking or profiling is basically to test how fast is your code executes and where the bottlenecks are? The main reason to do this is for optimization.

timeit

Python带有称为timeit的内置模块。你可以用它来计时小的代码段。timeit模块使用平台特定的时间函数,以便你获得尽可能最准确的时间。

Python comes with a in-built module called timeit. You can use it to time small code snippets. The timeit module uses platform-specific time functions so that you will get the most accurate timings possible.

所以,它允许我们比较每一项代码的两个传输值,然后优化脚本以提供更好的性能。

So, it allows us to compare two shipment of code taken by each and then optimize the scripts to given better performance.

timeit模块有一个命令行界面,但它也可以导入。

The timeit module has a command line interface, but it can also be imported.

有两种调用脚本的方法。让我们首先使用脚本,为此运行以下代码并查看输出。

There are two ways to call a script. Let’s use the script first, for that run the below code and see the Output.

import timeit
print ( 'by index: ', timeit.timeit(stmt = "mydict['c']", setup = "mydict = {'a':5, 'b':10, 'c':15}", number = 1000000))
print ( 'by get: ', timeit.timeit(stmt = 'mydict.get("c")', setup = 'mydict = {"a":5, "b":10, "c":15}', number = 1000000))

Output

by index: 0.1809192126703489
by get: 0.6088525265034692

在上面我们使用了两种不同的方法,即通过下标和get来访问字典键值。我们执行语句100万次,因为它对于非常小的数据执行的速度太快。现在,我们可以看到与get相比,索引访问快得多。我们可以多次运行代码,执行时间会有细微的变化,以获得更好的理解。

Above we use two different method .i.e. by subscript and get to access the dictionary key value. We execute statement 1 million times as it executes too fast for a very small data. Now we can see the index access much faster as compared to the get. We can run the code multiply times and there will be slight variation in the time execution to get the better understanding.

另一种方法是在命令行中运行以上测试。我们开始吧,

Another way is to run the above test in the command line. Let’s do it,

c:\Python\Python361>Python -m timeit -n 1000000 -s "mydict = {'a': 5, 'b':10, 'c':15}" "mydict['c']"
1000000 loops, best of 3: 0.187 usec per loop

c:\Python\Python361>Python -m timeit -n 1000000 -s "mydict = {'a': 5, 'b':10, 'c':15}" "mydict.get('c')"
1000000 loops, best of 3: 0.659 usec per loop

上述输出可能因你的系统硬件和你系统中当前正在运行的所有应用程序而异。

Above output may vary based on your system hardware and what all applications are running currently in your system.

下面我们可以使用timeit模块,如果我们想调用一个函数。因为我们可以在函数中添加多个语句进行测试。

Below we can use the timeit module, if we want to call to a function. As we can add multiple statement inside the function to test.

import timeit

def testme(this_dict, key):
   return this_dict[key]

print (timeit.timeit("testme(mydict, key)", setup = "from __main__ import testme; mydict = {'a':9, 'b':18, 'c':27}; key = 'c'", number = 1000000))

Output

0.7713474590139164

Object Oriented Python - Libraries

Requests − Python Requests Module

Requests是Python的一个模块,它是一个优雅而简单的Python HTTP库。有了它,你可以发送各种HTTP请求。通过这个库,我们可以添加头信息、表单数据、多部分文件和参数,以及访问响应数据。

Requests is a Python module which is an elegant and simple HTTP library for Python. With this you can send all kinds of HTTP requests. With this library we can add headers, form data, multipart files and parameters and access the response data.

由于Requests不是一个内置模块,因此我们首先需要安装它。

As Requests is not a built-in module, so we need to install it first.

你可以通过在终端中运行以下命令来安装它:

You can install it by running the following command in the terminal −

pip install requests

安装模块后,你可以通过在Python shell中键入以下命令来验证安装是否成功。

Once you have installed the module, you can verify if the installation is successful by typing below command in the Python shell.

import requests

如果安装成功,你将不会看到任何错误消息。

If the installation has been successful, you won’t see any error message.

Making a GET Request

作为示例,我们将使用“pokeapi”

As a means of example we’ll be using the “pokeapi”

pokeapi

Output −

pokeapi output

Making POST Requests

requests 库方法适用于所有当前使用的 HTTP 动词。如果您想对 API 终结点发出一个简单的 POST 请求,则可以这样做 −

The requests library methods for all of the HTTP verbs currently in use. If you wanted to make a simple POST request to an API endpoint then you can do that like so −

req = requests.post(‘http://api/user’, data = None, json = None)

与我们之前的 GET 请求相同,但这具有两个额外的关键字参数 −

This would work in exactly the same fashion as our previous GET request, however it features two additional keyword parameters −

  1. data which can be populated with say a dictionary, a file or bytes that will be passed in the HTTP body of our POST request.

  2. json which can be populated with a json object that will be passed in the body of our HTTP request also.

Pandas: Python Library Pandas

Pandas 是一个开源 Python 库,提供高性能的数据操作和分析工具,并使用其强大的数据结构。Pandas 是数据科学中最广泛使用的 Python 库之一。它主要用于数据整理,原因有很多:功能强大且灵活。

Pandas is an open-source Python Library providing high-performance data manipulation and analysis tool using its powerful data structures. Pandas is one of the most widely used Python libraries in data science. It is mainly used for data munging, and with good reason: Powerful and flexible group of functionality.

基于 Numpy 包,关键数据结构称为 DataFrame。这些数据框架使我们能够存储和操作表格数据,其中包括观测行和变量列。

Built on Numpy package and the key data structure is called the DataFrame. These dataframes allows us to store and manipulate tabular data in rows of observations and columns of variables.

有几种创建 DataFrame 的方法。一种方法是使用词典。例如 −

There are several ways to create a DataFrame. One way is to use a dictionary. For example −

dataframe

Output

dataframe output

从输出中,我们可以看到新的 brics DataFrame,Pandas 已为每个国家分配了一个键,从数值 0 到 4。

From the output we can see new brics DataFrame, Pandas has assigned a key for each country as the numerical values 0 through 4.

如果不给出 0 到 4 的索引值,而希望有不同的索引值(例如,两个字母的国家代码),也可以轻松地做到 −

If instead of giving indexing values from 0 to 4, we would like to have different index values, say the two letter country code, you can do that easily as well −

将下面的代码添加到上面的代码中,得到

Adding below one lines in the above code, gives

brics.index = ['BR', 'RU', 'IN', 'CH', 'SA']

Output

dataframe brics index

Indexing DataFrames

indexing dataframes

Output

indexing dataframes output

Pygame

Pygame 是一个开源且跨平台的库,用于制作包括游戏在内的多媒体应用程序。它包含计算机图形和声音库,旨在与 Python 编程语言配合使用。您可以使用 Pygame 开发很多酷炫的游戏。

Pygame is the open source and cross-platform library that is for making multimedia applications including games. It includes computer graphics and sound libraries designed to be used with the Python programming language. You can develop many cool games with Pygame.’

Overview

Pygame 由多个模块组成,每个模块处理一组特定任务。例如,display 模块处理显示窗口和屏幕,draw 模块提供绘制形状的函数,key 模块处理键盘。这些只是库中的几个模块。

Pygame is composed of various modules, each dealing with a specific set of tasks. For example, the display module deals with the display window and screen, the draw module provides functions to draw shapes and the key module works with the keyboard. These are just some of the modules of the library.

Pygame 库的主页位于 https://www.pygame.org/news

The home of the Pygame library is at https://www.pygame.org/news

要制作 Pygame 应用程序,请按照以下步骤:

To make a Pygame application, you follow these steps −

导入 Pygame 库

Import the Pygame library

import pygame

初始化 Pygame 库

Initialize the Pygame library

pygame.init()

创建一个窗口。

Create a window.

screen = Pygame.display.set_mode((560,480))
Pygame.display.set_caption(‘First Pygame Game’)

Initialize game objects

Initialize game objects

在这一步,我们会加载图片,加载声音,进行对象定位,设置一些状态变量等。

In this step we load images, load sounds, do object positioning, set up some state variables, etc.

Start the game loop.

Start the game loop.

它只是一个循环,处理事件,检查输入,移动对象并绘制它们。循环的每次迭代称为一次帧。

It is just a loop where we continuously handle events, checks for input, move objects, and draw them. Each iteration of the loop is called a frame.

将以上所有逻辑及入到下方程序中,

Let’s put all the above logic into one below program,

Pygame_script.py

Pygame_script.py

pygame script

Output

pygame script output

Beautiful Soup: Web Scraping with Beautiful Soup

网络抓取背后的总想法是获取存在于网站上的数据,并将其转换为可用于分析的格式。

The general idea behind web scraping is to get the data that exists on a website, and convert it into some format that is usable for analysis.

它是一个用于从 HTML 或 XML 文件中提取数据的 Python 库。凭借您最喜欢的解析器,它提供了解析、搜索和修改解析树的惯用方法。

It’s a Python library for pulling data out of HTML or XML files. With your favourite parser it provide idiomatic ways of navigating, searching and modifying the parse tree.

由于 BeautifulSoup 不是内置库,因此我们需要在尝试使用它之前将其安装。若要安装 BeautifulSoup,请运行以下命令:

As BeautifulSoup is not a built-in library, we need to install it before we try to use it. To install BeautifulSoup, run the below command

$ apt-get install Python-bs4 # For Linux and Python2
$ apt-get install Python3-bs4 # for Linux based system and Python3.

$ easy_install beautifulsoup4 # For windows machine,
Or
$ pip instal beatifulsoup4 # For window machine

安装完成后,我们就可以运行一些示例并详细探索 Beautifulsoup,

Once the installation is done, we are ready to run few examples and explores Beautifulsoup in details,

beautifulsoup in details

Output

beautifulsoup in details output

以下是一些导航该数据结构的简单方法 −

Below are some simple ways to navigate that data structure −

data structure

一项常见任务是从页面 <a> 标签中提取所有 URL −

One common task is extracting all the URLs found within a page’s <a> tags −

urls

另一项常见任务是从页面中提取所有文本 −

Another common task is extracting all the text from a page −

text from page