Python关键代码总结

Abstract: Python关键代码,主要关于类与对象、封装。

1.类与对象

Python 是一种面向对象的程序语言,因此它也有类(Class)与对象(Object)这两个概念。在了解 Python 面向对象编程的案例前,我们需要先熟悉面向对象编程的一些基本概念:

  • 类 (Class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
  • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
  • 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
  • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
  • 实例变量:定义在方法中的变量,只作用于当前实例的类。
  • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,一个「狗」类的对象派生自「动物」类,这是模拟”是一个(is-a)”关系(狗是一种动物)。
  • 实例化:创建一个类的实例,类的具体对象。
  • 方法:类中定义的函数。
  • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
1
2
3
4
5
class Vehicle:
pass

car = Vehicle()
print (car) //如car是Vehicle的一个实例/对象
1
2
3
4
5
6
7
8
class Vehicle:
def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
self.number_of_wheels = number_of_wheels
self.type_of_tank = type_of_tank
self.seating_capacity = seating_capacity
self.maximum_velocity = maximum_velocity

tesla_model_s = Vehicle(4, 'electric', 5, 250)

我们将发送信息到对象的过程称为方法,即对象的行为:

1
2
3
4
5
6
7
8
9
10
11
12
class Vehicle:
def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
self.number_of_wheels = number_of_wheels
self.type_of_tank = type_of_tank
self.seating_capacity = seating_capacity
self.maximum_velocity = maximum_velocity

def number_of_wheels(self):
return self.number_of_wheels

def set_number_of_wheels(self, number):
self.number_of_wheels = number
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Vehicle:
def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
self.number_of_wheels = number_of_wheels
self.type_of_tank = type_of_tank
self.seating_capacity = seating_capacity
self.maximum_velocity = maximum_velocity

@property
def number_of_wheels(self):
return self.number_of_wheels

@number_of_wheels.setter
def number_of_wheels(self, number):
self.number_of_wheels = number

以上语句实现了两个方法,number_of_wheels 和 set_number_of_wheels。我们可以称为 getter & setter,因为第一个方法获取了属性值,而第二个方法将为该属性设置一个新的值。在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数

在 Python 中,我们能使用 @property (decorators) 定义 getter & setter.

1
2
3
print(tesla_model_s.number_of_wheels) # 4
tesla_model_s.number_of_wheels = 2 # setting number of wheels to 2
print(tesla_model_s.number_of_wheels) # 2

使用这些方法作为属性.

2.封装:隐藏信息

封装是一种限制直接访问目标属性和方法的机制,但同时它又有利于对数据(对象的方法)进行操作。

封装是一种将抽象性函数接口的实现细节部分包装、隐藏起来的方法。同时,它也是一种防止外界调用端,去访问对象内部实现细节的手段,这个手段是由编程语言本身来提供的。

对象所有的内部表征对于外部来说都是隐藏的,只有对象能直接与内部数据交互。首先,我们需要理解公开(public)和私有(non-public)实例变量和方法

2.1 公开实例变量

初始化公开实例变量:

1
2
3
4
5
6
7
8
9
class Person:
def __init__(self, first_name):
self.first_name = first_name

tk = Person('TK')
print(tk.first_name)

class Person:
first_name = 'TK'

给tk对象赋值,以及二次赋值

1
2
3
4
5
6
7
8
//给tk对象赋值,以及二次赋值
class Person:
def __init__(self,first_name):
self.first_name = first_name

tk = Person('TK')
tk.first_name = 'kaios'
print(tk.first_name)

2.2 私有实例变量

和公开实例变量一样,我们可以使用 constructor 方法或在类的内部声明而定义一个私有实例变量。语法上的不同在于私有实例变量在变量名前面加一个下划线

1
2
3
4
5
6
7
8
9
class Person:
def __init__(self, first_name, email):
self.first_name = first_name
self._email = email
//上述定义的 email 变量就是私有变量。

tk = Person('kaio','tk@email.com')
print(tk._email)
//输出私有变量值

我们可以访问并且更新它,私有变量仅是一个约定,即他们需要被视为 API 非公开的部分。所以我们可以使用方法在类的定义中完成操作,例如使用两种方法展示私有实例的值与更新实例的值:

1
2
3
4
5
6
7
8
9
10
class Person:
def __init__(self, first_name, email):
self.first_name = first_name
self._email = email

def update_email(self, new_email):
self._email = new_email

def email(self):
return self._email

先初始化 Person 类并赋值,然后通过定义的方法访问并打印私有变量的值。如我们直接赋值给私有变量新的值,那么打印出来还是原有的值,我们只能通过在类里面定义的方法进行操作而更新私有变量。

1
2
3
4
5
6
tk = Person('TK', 'tk@mail.com')
print(tk.email()) # => tk@mail.com
tk._email = 'new_tk@mail.com'
print(tk.email()) # => tk@mail.com
tk.update_email('new_tk@mail.com')
print(tk.email()) # => new_tk@mail.com

2.3 公开方法

对于公开方法(public methods),我们同样能在类以外的地方调用,以下定义了一个类与方法:

1
2
3
4
5
6
7
8
9
10
class Person:
def __init__(self, first_name, age):
self.first_name = first_name
self._age = age

def show_age(self):
return self._age

tk = Person('TK', 25)
print(tk.show_age())

2.4 私有方法

私有方法应该要看作 API 的私有部分。如下我们声明了私有方法_get_age和公开方法 show_age。show_age 方法可以在类的外部调用,而_get_age 只能在类内部使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
class Person:
def __init__(self, first_name, age):
self.first_name = first_name
self._age = age

def show_age(self):
return self._get_age()

def _get_age(self):
return self._age

tk = Person('TK', 25)
print(tk.show_age()) # => 25

2.5 封装小结

通过程序封装,我们确保了对象的内部表征对外是隐藏的。而面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。继承完全可以理解成类之间的类型和子类型关系。

若我们有一辆车,且知道车轮数、座位容量和最大时速,那么一辆电动车类就继承常规汽车类中的相同属性.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Car:
def __init__(self, number_of_wheels, seating_capacity, maximum_velocity):
self.number_of_wheels = number_of_wheels
self.seating_capacity = seating_capacity
self.maximum_velocity = maximum_velocity

//更新类中的一个对象:
my_car = Car(4, 5, 250)
print(my_car.number_of_wheels)
print(my_car.seating_capacity)
print(my_car.maximum_velocity)

//初始化对象后,Python 可以将父类(parent class)作为参数应用到子类(child class)中。因此电动车类可以从汽车类继承对象。

class ElectricCar(Car):
def __init__(self, number_of_wheels, seating_capacity, maximum_velocity):
Car.__init__(self, number_of_wheels, seating_capacity, maximum_velocity)

//我们不需要实现其他方法,因为电动汽车类已经从汽车类继承了对象:

my_electric_car = ElectricCar(4, 5, 250)
print(my_electric_car.number_of_wheels) # => 4
print(my_electric_car.seating_capacity) # => 5
print(my_electric_car.maximum_velocity) # => 250

3.Reference

科赛 x 机器之心 | 从零上手Python关键代码

Thanks!