Python面向对象操作


开始

类和实例

类是创建实例的模板,而实例则是一个一个具体的对象,各个实例拥有的数据都互相独立,互不影响。

在Python中,定义类是通过class关键字:

1
2
class Student(object):
pass

(object)表示该类是从哪个类继承下来的,如果未指定,就使用object类,这是所有类最终都会继承的类。

创建实例:

1
2
3
4
5
6
7
8
class Student(object):
pass

# 等同于main函数
if __name__ == "__main__":
student = Student()
print(student) # print <__main__.Student object at 0x000000B7FFB09358>
print(Student) # print <class '__main__.Student'>

函数和方法

方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据。

使用__init__来创建构造函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Student(object):

def __init__(self, name, score):
self.name = name
self.score = score

# 定义一个方法
def say(self, msg):
return "%s: %s" % (self.name, msg)


if __name__ == "__main__":
student = Student("Jowan", 100)
print(student.name, student.score, student.say("Hello World!"))
# print Jowan 100 Jowan: Hello World!

类里面的所有方法都是以self为第一个参数,就指向创建的实例本身,在调用的时候不需要传入值。

访问限制

Python默认属性是无访问限制的,可以自由调用和修改,如果需要设置不被外部访问,需要在开头加上两个下划线_,就变成私有(private)的了:

1
2
3
4
5
6
7
8
9
10
11

class Student(object):

def __init__(self, name, score):
self.__name = name
self.__score = score


if __name__ == "__main__":
student = Student("Jowan", 100)
print(student.__name, student.__score)

这时候在外面在调用私有变量,编译器会提示你:

如果还是执意运行的话,就会报错:

1
AttributeError: 'Student' object has no attribute '__name'

当我们要访问这个私有变量的时候,需要这样操作,添加对应的getset方法:

1
2
3
4
5
6
7
8
9
10
11
12

def get_name(self):
return self.__name

def __set_name__(self, name):
self.__name = name

def get_score(self):
return self.__score

def set_score(self, score):
self.__score = score

其实双下划线开头的实例变量并不是一定不能从外部访问,不能直接访问__name的原因是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量:

1
2
print(student._Student__name, student._Student__score)
# print Jowan 100

继承

前面说了(object)表示继承类某个类,如果没有就写object,下面声明一个父类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Animal(object):
def run(self):
print('Animal is running...')


class Dog(Animal):
pass


class Cat(Animal):
pass


if __name__ == "__main__":
dog = Dog()
dog.run()
# print Animal is running...

cat = Cat()
cat.run()
# print Animal is running...

实例属性与类属性

Python包括实例属性和类属性。
实例属性是实例绑定属性或者通过self设置,而类属性是这个类的所有实例共享:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Student(object):
classField = "classField"

def __init__(self, name):
self.name = name


if __name__ == "__main__":
student1 = Student("Student1")
print(student1.name)
student2 = Student("Student2")
print(student2.name)
print(student1.classField)
print(student2.classField)
"""
print
Student1
Student2
classField
classField
"""

注意:不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性。

获取对象类型

type()

使用type()来判断对象类型,返回对应的Class类型:

1
print(type(123)) # <class 'int'>

使用types模块中的常量来判断一个对象是否是一个函数类型:

1
2
3
4
type(fn) # types.FunctionType
type(abs) # types.BuiltinFunctionType
type(lambda x: x) # types.LambdaType
type((x for x in range(10))) # types.GeneratorType

isinstance()

使用isinstance()来判断有继承关系的类型:

1
2
3
4
5
6
7
8
# object -> Animal -> Dog -> Husky
a = Animal()
b = Dog()
h = Husky()
print(isinstance(h, Husky)) # True
print(isinstance(h, Dog)) # True
print(isinstance(h, Anima)) # True
print(isinstance(d, Husky)) # False

基本类型也可以用isinstance来判断:

1
2
3
isinstance('a', str) # True
isinstance(123, int) # True
isinstance(b'a', bytes) # True

同时还能多种类型里面判断:

1
2
isinstance([1, 2, 3], (list, tuple)) # True
isinstance((1, 2, 3), (list, tuple)) # True

dir()

感谢