面向对象编程
在面向对象编程中(OOP), 我们可以定义类作为蓝图,用于在 Python 中创建具有属性和方法(与对象相关的功能)的对象。
定义类的一般语法:
class <className>:
<class_attribute_name> = <value>
def __init__(self,<param1>, <param2>, ...):
self.<attr1> = <param1>
self.<attr2> = <param2>
.
.
.
# As many attributes as needed
def <method_name>(self, <param1>, ...):
<code>
# As many methods as needed
self是类的实例(用类创建的对象)的引用。
如你所见,类可以有很多不同的元素,让我们来分析一下它们的细节:
类的头部
类定义的第一行是class关键字和类名:
class Dog:
class House:
class Ball:
如果一个类继承了另外一个类的属性和方法,我们会在括号中看到该类的名称:
class Poodle(Dog):
class Truck(Vehicle):
class Mom(FamilyMember):
Python 中, 类名用大驼峰(也称为 Pascal Case),名称中的每个一个单词都是以大写字母开头。例如:FamilyMember
init和实例属性
接下来,我们将使用类在 Python 中创建对象,就像我们根据图纸建造真正的房屋一样。
对象中的属性来自于我们在类中定义,而这些属性通常是在init方法中被初始化,而init方法会在创建类的实例时被执行。
这是一般语法:
def __init__(self, <parameter1>, <parameter2>, ...):
self.<attribute1> = <parameter1> # Instance attribute
self.<attribute2> = <parameter2> # Instance attribute
.
.
.
# As many instance attributes as needed
我们可以根据需要来给类指定尽可能多的属性。
Dog类的一个init方法例子:
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
注意名称init中的前后的双下划线
如何创建类的实例
要创建Dog类的实例,我们需要指定 name 和 age 属性。
my_dog = Dog("Nora", 10)
很好。现在我们已经准备好了一个可以在代码中使用的 Dog 实例了。
有些类,可以不需要任何参数来创建实例。 这种情况我们只需要一个空括号,例如:
class Circle:
def __init__(self):
self.radius = 1
创建实例:
>>> my_circle = Circle()
self像是一个“幕后”的参数,即使我们在方法的定义中看到它,但你传参数时可以不用考虑它。
默认参数
我们可以为类的属性指定默认值,但如果使用者想自己赋值,也是可以的。
这种情况下,我们可以在参数列表中写上形如:< attribute >=< value >
例如:
class Circle:
def __init__(self, radius=1):
self.radius = radius
现在我们创建Circle实例,你可以通过忽略 radius 参数使用它的默认值,也可以传入一个自己的值:
# Default value
>>> my_circle1 = Circle()
# Customized value
>>> my_circle2 = Circle(5)
如何获取实例的属性
访问实例属性,可以用下面的语法:
<object_variable>.<attribute>
例如:
# Class definition
>>> class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
# Create instance
>>> my_dog = Dog("Nora", 10)
# Get attributes
>>> my_dog.name
'Nora'
>>> my_dog.age
10
如何更新实例的属性
更新实例的属性,我们可以用下面的语法:
<object_variable>.<attribute> = <new_value>
例如:
>>> class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
>>> my_dog = Dog("Nora", 10)
>>> my_dog.name
'Nora'
# Update the attribute
>>> my_dog.name = "Norita"
>>> my_dog.name
'Norita'
如何删除实例属性
要删除实例属性,可以用下面的语法:
del <object_variable>.<attribute>
>>> class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
>>> my_dog = Dog("Nora", 10)
>>> my_dog.name
'Nora'
# Delete this attribute
>>> del my_dog.name
>>> my_dog.name
Traceback (most recent call last):
File "<pyshell#77>", line 1, in <module>
my_dog.name
AttributeError: 'Dog' object has no attribute 'name'
如何删除一个实例
同样的,删除实例我们也可以用del:
>>> class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
>>> my_dog = Dog("Nora", 10)
>>> my_dog.name
'Nora'
# Delete the instance
>>> del my_dog
>>> my_dog
Traceback (most recent call last):
File "<pyshell#79>", line 1, in <module>
my_dog
NameError: name 'my_dog' is not defined
公开 vs 非公开 的属性
在 Python 中,我们没有用访问修饰符来限制对实例属性的访问,而是依靠命名惯例来做到这一点。
例如,在属性前添加一个前导下划线,就可以告诉开发者这是一个非公开的属性。
例如:
class Dog:
def __init__(self, name, age):
self.name = name # Public attribute
self._age = age # Non-Public attribute
Python 中类的属性
类的属性由类的所有实例共享。所有实例都可以访问这些属性,如果这些属性被修改,这些实例将都会受到影响。
class Dog:
# Class attributes
kingdom = "Animalia"
species = "Canis lupus"
def __init__(self, name, age):
self.name = name
self.age = age
通常,它们写在init方法的前面。
如何获取一个类属性
<class_name>.<attribute>
例如:
>>> class Dog:
kingdom = "Animalia"
def __init__(self, name, age):
self.name = name
self.age = age
>>> Dog.kingdom
'Animalia'
你可以使用同样的语法在类里面获取它的值。
如何更新一个类属性
要更新一个类属性,我们使用下面的语法:
<class_name>.<attribute> = <value>
例如:
>>> class Dog:
kingdom = "Animalia"
def __init__(self, name, age):
self.name = name
self.age = age
>>> Dog.kingdom
'Animalia'
>>> Dog.kingdom = "New Kingdom"
>>> Dog.kingdom
'New Kingdom'
如何删除一个类属性
我们使用del一个类属性。例如:
>>> class Dog:
kingdom = "Animalia"
def __init__(self, name, age):
self.name = name
self.age = age
>>> Dog.kingdom
'Animalia'
# Delete class attribute
>>> del Dog.kingdom
>>> Dog.kingdom
Traceback (most recent call last):
File "<pyshell#88>", line 1, in <module>
Dog.kingdom
AttributeError: type object 'Dog' has no attribute 'kingdom'
如何定义方法
方法用于表示类实例的功能。
如果我们在实例方法的定义中写上self.< attribute >,那么实例方法就可以调用实例属性。
下面是定义方法的基本语法,这些方法一般定义在init方法后面:
class <ClassName>:
# Class attributes
# __init__
def <method_name>(self, <param1>, ...):
<code>
这些实例方法可能有 0 个、1 个或多个参数(就像函数!),但self必须是第一个参数。
例如,下面的bark方法没有参数(除了self):
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
print(f"woof-woof. I'm {self.name}")
要调用这个方法,我们用下面的语法:
<object_variable>.<method>(<arguments>)
例如:
# Create the instance
>>> my_dog = Dog("Nora", 10)
# Call the method
>>> my_dog.bark()
woof-woof. I'm Nora
Player类里定义了只有一个参数的increment_speed方法:
class Player:
def __init__(self, name):
self.name = name
self.speed = 50
def increment_speed(self, value):
self.speed += value
调用此方法:
# Create instance
>>> my_player = Player("Nora")
# Check initial speed to see the change
>>> my_player.speed
50
# Increment the speed
>>> my_player.increment_speed(5)
# Confirm the change
>>> my_player.speed
55
要添加更多参数,只需要将多个参数用逗号分隔。建议在每个逗号后面加一个空格。