1 类概述
Python是面向对象编程语言。面向对象编程(OOP)是一种方法学,即做事的方法。编写类时,程序员定义一大类对象都有的通用行为。基于类创建对象时,每个对象都自动具备这种通用行为,然后可根据需要赋予每个对象独特的个性。
类是一个对象的蓝图。类不能做任何事,因为它是一个蓝图。只有在运行时实例化对象的时候,对象才会存在。所以,开发者在编写类代码时,它只是一个类的定义,而不是一个对象。类的函数也叫作方法,类的变量通常作为属性来访问。
class People:
def __init__(self, name, age):
self.name = name
self.age = age
def say_hi(self):
print("Hi, my name is {}, and I'm {}".format(self.name, self.age))
# class instance 类的实例
someone = People(name='steve', age=20)
print(someone.name)
print(someone.age)
someone.say_hi()
当创建一个对象的时候,类实例化为该对象。
使用面向对象编程可模拟显示情景。
- 根据类来创建对象被称为实例化。
- 在Python中,首字母大写的名称指的是类。
- 类中的函数被称为方法。
每个定义行末,都必须有一个冒号。
1.1 私有属性和受保护属性
class People:
def __init__(self, name, age):
self.name = name
self.age = age
# 受保护属性,类内外均可使用
self._protect_var = 10
# 私有属性,只能在类内部才能访问(其实在类内部重命名了)
self.__private_var = 10
def say_hi(self):
print("Hi, my name is {}, and I'm {}".format(self.name, self.age))
def set_var(self, var):
self.__private_var = var
def get_var(self):
return self.__private_var
# class instance 类的实例
someone = People(name='steve', age=20)
someone._protect_var = 30
print(someone._People__private_var)
print(dir(someone))
1.2 类的property
class People:
def __init__(self, name, age):
self.__name = name
self.__age = age
@property
def name(self):
return self.__name
@property
def age(self):
return self.__age
@age.setter
def age(self, age):
self.__age = age
@name.setter
def name(self, name):
self.__name = name
someone = People(name='steve', age=30)
print(someone.name)
someone.name = 'steve jobs'
print(someone.name)
2 方法__init__()
方法__init__()是一个特殊的方法,即类的构造函数。每当我们根据类创建新实例时,Python都会自动运行它。在这个方法的名称中,开头和末尾各有两个下划线,这是一种约定,旨在避免Python默认方法与普通方法发生名称冲突。
- 形参self必不可少,还必须位于其他形参前面。当Python调用这个方法__init__()创建类实例时,将自动传入实参self。每个与类相关联的方法调用都自动传入实参self,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。
- 以self为前缀的变量都可供类中的所有方法使用,程序员可通过类的任何实例来访问这些变量。
- 通过实例访问的变量称为属性。
关键字self描述当前的类,这和其在C++中的作用是相同的。所有类的变量前面必须有一个self,以便可以认出这是类的成员,否则,它们将会被当做局部变量
3 访问属性
要访问实例的属性,可使用句点表示法。
句点表示法在Python中很常见,这种语法演示了Python如何获悉属性的值。Python先找到实例,再查找与这个实例相关联的属性。
4 调用方法
要调用方法,可指定实例的名称和要调用的党发,并用句点分隔它们。
5 创建多个实例
可按需求根据类创建任意数量的实例。一个独立的实例,都有自己的一组属性,能够执行相同的操作。
程序员可按需求根据一个类创建任意数量的实例,条件是将每个实例都存储在不同的变量中,或占用列表或字典的不同位置。
6 使用类和实例
程序员可以修改实例的属性,也可以编写方法以特定的方式来进行修改。
6.1 给属性指定默认值
类中的每个属性都必须有初始值,例如0或者空字符串。
设置默认值时,在方法__init__()内指定初始值,无需包含初始值的形参。
6.1.1 类的属性和实例属性
class Student:
count = 0
def __init__(self, name):
Student.count += 1
self.name = name
s1 = Student('A')
s2 = Student('B')
s3 = Student('C')
print(Student.count)
6.1.2 类方法和实例方法
class People:
def __init__(self, name, age):
self.name = name
self.age = age
def say_hi(self):
"""实例的方法"""
print("Hi, my name is {}, and I'm {}".format(self.name, self.age))
@classmethod
def test_0(cls):
print("这是一个类方法。")
cls.test_1()
@staticmethod
def test_1():
print("这是一个静态方法。")
someone = People(name='Steve Jobs', age=28)
someone.say_hi()
someone.test_0()
someone.test_1()
People.test_0()
People.test_1()
6.2 修改属性的值
6.2.1 直接修改属性的值
要修改属性的值,最简单的方法是通过实例直接访问。
6.2.2 通过方法修改属性的值
无需直接访问属性,可将值传递给一个方法,由它在内部更新。
6.2.3 通过方法对属性的值进行递增
将属性值递增到特定的值,而不是将设置为全新的值。
7 继承
一个类继承另一个类时,它将自动获得另一个类的所有属性和方法。原有的类称为父类,而新类称为子类。子类继承了其弗雷的所有属性和方法,同时还可以定义自己的属性和方法。
此外,Python支持多继承,即一个子类可以继承多个父类或基类。只要每个父类中的变量和方法与其他变量和方法不冲突,新的子类可以访问它们。但是如果有任何冲突,来自父类的冲突变量和方法在继承顺序中具有优先性。
当一个Python类继承自一个基类,父类的所有变量和方法都是可用的。变量可以使用,方法可以覆盖。
当设计多继承时,当共享相同的变量名或方法名时,必须使用父类名称,以避免混淆。
class Animal:
def eat(self):
print('Animal is eating.')
class Bird(Animal):
def sing(self):
print("Bird is singing.")
def eat(self):
print('Bird is eating.')
class Dog(Animal):
def eat(self):
print("Dog is eating.")
class Cat(Animal):
def eat(self):
print("Cat is eating.")
bird = Bird()
bird.eat()
bird.sing()
dog = Dog()
dog.eat()
animal = Animal()
7.1 子类的方法
创建子类的实例时,Python首先需要完成的任务是给父类的所有属性赋值。
7.1.1 super()函数
super()是一个特殊函数,帮助Python将父类和子类关联起来。这行代码让Python调用父类的方法__init__,让子类实例包含父类的所有属性。父类也称超类。
函数super()需要两个实参,子类名和对象self。为帮助Python将父类和子类关联起来,这些实参必不可少。
7.1.2 给子类定义属性和方法
让一个类继承另一个类后,可添加区分子类和父类所需要的新属性和方法。
7.1.3 重写父类的方法
对于父类的方法,只要父类不符合子类模拟的实物行为,都可以对其重写。为此,可在子类中定义这样一个方法,即它与要重写的父类方法同名。这样Python将不会考虑这个父类方法,而只关注你在子类中定义的相应方法。
使用继承时,可让子类保留从父类那里继承而来的精华,并剔除需要的糟粕。
7.1.4 将实例作为属性
为类添加的细节越多,属性和方法清单越来越长。这种情况下,需要类的一部分作为一个独立的类提取出来。程序员可以将大型类拆分为多个协同工作的小类。
8 导入类
为遵循Python的总体理念,应让文件尽可能整洁。因此,Python允许将类存储在模块中,然后再主程序中导入所需的模块。
8.1 导入单个类
通过类移到一个模块中,并导入该模块,程序员依然可以使用其所有功能,但主程序文件变得整洁而易于阅读。
这让程序员将大部分逻辑存储再独立的文件中,确认类工作后,只需要专注于主程序的高级逻辑。
8.2 再一个模块中存储多个类
同一个模块中的类之间应存在某种相关性,但可根据需要再一个模块中存储任意数量的类。
8.3 从一个模块中导入多个类
可根据需要在程序文件中导入任意数量的类,从一个模块中导入多个类,用逗号分隔了各个类。导入必要的类,就可根据需要创建每个类的任意数量的实例。
8.4 导入整个模块
导入整个模块,再使用句点表示法访问需要的类。
由于创建类实例的代码都包含类模块,因此不会与当前文件使用的任何名称发生冲突。
8.5 导入模块中的所有类
语法如下:
from module_name import *
不推荐这种导入方式。
- 1、文件开头的import语句,就能清楚地知道程序使用了哪些类。但这种导入方式没有明确地指出程序员使用了模块的哪些类。
- 2、这种导入的方式可能引发名称方面的错误。
从一个模块中导入很多类,最好导入整个模块。
8.6 在一个模块中导入另一个模块
当一个模块中的类依赖于另一个模块中的类,在这种情况下,可在一个模块中导入必要的类。
8.7 自定义工作流程
一开始应让代码结构尽可能简单。先在一个文件中完成所有工作,确认一切都能正常运行,在将类移动到独立的模块。
8.8 Python标准库
Python标准库是一组模块,安装的Python都包含它。
字典让程序员将信息关联起来,但它们不记录程序员添加键值对的顺序,要创建字典并记录其中的键值对添加的顺序,可使用模块collections中的OrderDict类。(其行为几乎和字典相同,区别只在于记录了键值对的添加顺序)
这是一个不错的类,其兼具列表和字典的主要优点(在将信息关联起来的同时保留原来的顺序)。当程序员开始关心显示建模时,可能发现有序字典正好满足需求。
9 类编码风格
- 类名应采用驼峰命名法,即将类名中的每个单词的首字母都大写,而不使用下划线。实例名和模块名都都采用小写格式,并在单词之间加上下划线。
- 对于类,都应紧跟在类定义后面包含一个文档字符串。
这种文档字符串简要表述类的功能,并遵循编写函数的文档字符串采用的格式约定。
- 可使用空行来组织代码,,但不能滥用。在类中,可使用一个空行来分割方法;子模块中,可使用两个空行来分割类。
- 在同时导入标准库中的模块和程序员自己编写的模块时,先编写导入标准库的import语句,在添加一个空行,然后再编写导入程序员自己编写的模块。
10 结构化编程
结构化编程(procedural programming),即在这种情况下使用的是过程和结构。过程也叫作函数。包含在一个对象中中函数,叫做方法。
当函数当做对象的一部分讨论时,使用方法这个术语而不是函数。
10.1 结构
结构是复杂的用户定义类型(UDT),它可以将许多变量包含在一起。
在电子产业中,很多软件开发工具包(SDK)任然按照结构化的方式来开发,提供函数库来控制一个电子设备(例如显卡或嵌入式系统)。
11 多态
因为多态表示为“多种形式”或“多种形状”,所以多态指具备多种形态的能力。
在类的环境中,我们可以使用具有多种形态的方法,即参数的多种不同的集合。
在Python中,开发者可以使用可选的参数来让方法具备多种功能。
12 数据隐藏(封装)
因为Python中所有内容都是共有的,所以Python不允许变量和方法声明为私有的或受保护的。
12.1 type和isinstance
a = [1, 2]
print(type(a))
class A():
pass
a = A()
print(type(a))
print(isinstance(a, A))
x = 1
print(isinstance(x, int))
c = [1, 2]
print(isinstance(c, str))
13 if name main
python文件有两种使用的方法.一是直接作为源代码执行,二是import到其他的python文件中被调用执行。因此if name == ‘main’: 的作用就是控制这两种情况执行代码的过程,在if name == ‘main’: 下的代码只有在第一种情况下(即文件作为源代码直接执行)才会被执行,而import到其他脚本中是不会被执行的。
if __name__ == '__main__':
print("hello, world")
动手试一试
9-1 餐馆:
class Restaurant():
def __init__(self, restaurant_name, cuisine_type):
self.restaurant_name = restaurant_name
self.cuisine_type = cuisine_type
def describe_restaurant(self):
print("The name of the restaurant is " + self.restaurant_name.title() +".")
print("The cuisine of the restaurant is " + self.cuisine_type + ".")
def open_restaurant(self):
print("This restaurant is open now.")
restaurant = Restaurant('which floor', 'chinese')
print(restaurant.restaurant_name)
print(restaurant.cuisine_type)
restaurant.describe_restaurant()
restaurant.open_restaurant()
9-2 三家餐馆:
class Restaurant():
def __init__(self, restaurant_name, cuisine_type):
self.restaurant_name = restaurant_name
self.cuisine_type = cuisine_type
def describe_restaurant(self):
print("The name of the restaurant is " + self.restaurant_name.title() +".")
print("The cuisine of the restaurant is " + self.cuisine_type + ".")
def open_restaurant(self):
print("This restaurant is open now.")
restaurant_0 = Restaurant('which floor', 'chinese')
restaurant_1 = Restaurant('cat love', 'chinese')
restaurant_2 = Restaurant('dog love', 'chinese')
restaurant_0.describe_restaurant()
restaurant_1.describe_restaurant()
restaurant_2.describe_restaurant()
9-3 用户:
class User():
def __init__(self, first_name, last_name, location):
self.first_name = first_name
self.last_name = last_name
self.location = location
def describe_user(self):
print("The user's first name is " + self.first_name)
print("The user's last name is " + self.last_name)
print("The user's location is " + self.location)
def great_user(self):
print(self.first_name.title() + " " + self.last_name.title() + ", hello world!")
user_0 = User('steve', 'jobs', 'china')
user_0.describe_user()
user_0.great_user()
user_1 = User('dog', 'white', 'china')
user_1.describe_user()
user_1.great_user()
user_2 = User('cat', 'mike', 'china')
user_2.describe_user()
user_2.great_user()
9-4 就餐人数:
class Restaurant():
def __init__(self, restaurant_name, cuisine_type):
self.restaurant_name = restaurant_name
self.cuisine_type = cuisine_type
self.number_served = 0
def describe_restaurant(self):
print("The name of the restaurant is " + self.restaurant_name.title() +".")
print("The cuisine of the restaurant is " + self.cuisine_type + ".")
def set_number_served(self, number_served):
self.number_served = number_served
def open_restaurant(self):
print("This restaurant is open now.")
def increment_number_served(self, increment_number):
self.number_served += increment_number
restaurant = Restaurant('which floor', 'Spicy crayfish')
print("There were " + str(restaurant.number_served) + " people at the table")
restaurant.set_number_served(100)
print("There were " + str(restaurant.number_served) + " people at the table")
restaurant.increment_number_served(120)
print("There were " + str(restaurant.number_served) + " people at the table")
9-5 尝试登录次数:
class User():
def __init__(self, first_name, last_name, location):
self.first_name = first_name
self.last_name = last_name
self.location = location
self.login_attempts = 0
def increment_login_attempts(self):
self.login_attempts += 1
def reset_login_attempts(self):
self.login_attempts = 0
def describe_user(self):
print("The user's first name is " + self.first_name)
print("The user's last name is " + self.last_name)
print("The user's location is " + self.location)
def great_user(self):
print(self.first_name.title() + " " + self.last_name.title() + ", hello world!")
user = User('steve', 'jobs', 'china')
print("The login attempts of the user is " + str(user.login_attempts) + ".")
user.increment_login_attempts()
user.increment_login_attempts()
print("The login attempts of the user is " + str(user.login_attempts) + ".")
user.reset_login_attempts()
print("The login attempts of the user is " + str(user.login_attempts) + ".")
9-6 冰淇淋小店:
class Restaurant():
def __init__(self, restaurant_name, cuisine_type):
self.restaurant_name = restaurant_name
self.cuisine_type = cuisine_type
def describe_restaurant(self):
print("The name of the restaurant is " + self.restaurant_name.title() +".")
print("The cuisine of the restaurant is " + self.cuisine_type + ".")
def open_restaurant(self):
print("This restaurant is open now.")
class IceCreamStand(Restaurant):
def __init__(self, restaurant_name, cuisine_type):
super().__init__(restaurant_name, cuisine_type)
self.flavors = ['strawberry', 'banana', 'apple']
def show_ice_cream_flavors(self):
print(self.flavors)
shop = IceCreamStand('which floor', 'chinese')
shop.show_ice_cream_flavors()
9-7 管理员:
class User():
def __init__(self, first_name, last_name, location):
self.first_name = first_name
self.last_name = last_name
self.location = location
self.login_attempts = 0
def increment_login_attempts(self):
self.login_attempts += 1
def reset_login_attempts(self):
self.login_attempts = 0
def describe_user(self):
print("The user's first name is " + self.first_name)
print("The user's last name is " + self.last_name)
print("The user's location is " + self.location)
def great_user(self):
print(self.first_name.title() + " " + self.last_name.title() + ", hello world!")
class Admin(User):
def __init__(self, first_name, last_name, location):
super().__init__(first_name, last_name, location)
self.privileges = ['can add post', 'can delete post', 'can ban user']
def show_privileges(self):
print("Administrator rights")
admin = Admin('steve', 'jobs', 'china')
admin.show_privileges()
9-8 权限:
class User():
def __init__(self, first_name, last_name, location):
self.first_name = first_name
self.last_name = last_name
self.location = location
self.login_attempts = 0
def increment_login_attempts(self):
self.login_attempts += 1
def reset_login_attempts(self):
self.login_attempts = 0
def describe_user(self):
print("The user's first name is " + self.first_name)
print("The user's last name is " + self.last_name)
print("The user's location is " + self.location)
def great_user(self):
print(self.first_name.title() + " " + self.last_name.title() + ", hello world!")
class Admin(User):
def __init__(self, first_name, last_name, location):
super().__init__(first_name, last_name, location)
self.privileges = Privileges()
class Privileges():
def __init__(self):
self.privileges = ['can add post', 'can delete post', 'can ban user']
def show_privileges(self):
print("Administrator rights")
admin = Admin('steve', 'jobs', 'china')
admin.privileges.show_privileges()
9-10 导入Restaurant类:
from restaurant import Restaurant
restaurant = Restaurant('which floor', 'china')
restaurant.open_restaurant()
class Restaurant():
def __init__(self, restaurant_name, cuisine_type):
self.restaurant_name = restaurant_name
self.cuisine_type = cuisine_type
self.number_served = 0
def describe_restaurant(self):
print("The name of the restaurant is " + self.restaurant_name.title() +".")
print("The cuisine of the restaurant is " + self.cuisine_type + ".")
def set_number_served(self, number_served):
self.number_served = number_served
def open_restaurant(self):
print("This restaurant is open now.")
def increment_number_served(self, increment_number):
self.number_served += increment_number
9-13 使用OrderedDict:
from collections import OrderedDict
glossary = OrderedDict()
for key, value in glossary.items():
print(key + ": " + value)
glossary["or"] = "或者"
glossary["and"] = "并且"
glossary["break"] = "跳出当前循环"
glossary["title"] = "以首字母大写显示"
glossary["float"] = "浮点数"
for key, value in glossary.items():
print(key + ": " + value)
9-14 骰子:
from random import randint
class Die():
def __init__(self, side=6):
self.side = side
def roll_die(self):
x = randint(1, self.side + 1)
print(x)
die = Die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
print()
die = Die(10)
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
print()
die = Die(20)
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()
die.roll_die()