Python的学习笔记--面向对象编程

模块


随着项目增大,功能越来越复杂,为了提高代码的复用性和降低功能间的耦合,提出了模块的概念。

python中有很多的模块,使用时候直接用import导入对应的包就可以使用。

1
import sys

这样就导入了一个sys模块,我们可以在代码中直接使用:

1
2
3
4
5
import sys
def func():
print (sys.argv)

func()

打印结果是当前的文件所在的路径。

解释sys的作用:
sys.argv 用list来存储命令行传过来的参数。第一个参数是.py文件名称,例如:

python3 xxx.py 运行结果就是['xxxx.py']

python3 xxxx.py abc 运行结果:['xxxx.py', 'abc']

在python的模块中,有一个特殊的变量__name__,这个变量的作用就是如果当前运行的是当前文件,这个变量的值就是__main__,所以如果想对一个模块使用测试方法,可以利用这个变量:

1
2
if __name__=="__main__":
func()

为了防止模块的命名有冲突,python 又引入了的概念,包其实可以简单的认为就是一个文件的路径,例如有如下目录结构:

1
2
3
4
5
6
A
|- abc.py

B
|- abc.py

上面的两个abc.py没有冲突。

我们也可以自己定义一个模块,比如:

mymodule文件:

1
2
def func_print():
print("my module")

对module的使用:

1
2
import mymodule 
mymodule.func_print()

如果模块的名称过长,可以使用as 关键字定义其他的别名。

1
2
import mymodule as m 
m.func_print()

如果在包下面的模块 可以使用包名.模块名,例如,我们可以使用 import modules.moduleA方式导入指定的包。


面向对象变成对象中重要的一个组成,在python中是使用关键字class定义类。

比如我们想定义一个动物类:

1
2
3
class Animal:
name="fantuan"

我们创建实例的时候,直接使用Animal(),具体使用如下:

1
2
animal=Animal()
print (animal.name)

上面的Animal的类中的name属性可以通过实例和类名都可以调用。因为python在实例上找不到的属性都会沿着实例的类寻找。例如代码:

1
2
3
4
5
animalA=Animal()
animalB=Animal()
print(Animal.name)
print (animalA.name)
print (animalB.name)

都能打印出name属性的值。

python支持动态属性的定义

1
2
animalA.type="哺乳类"
print(animalA.type)

如果创建一个类的对象的时候,如果需要初始化变量,可以使用__init__方法。

1
2
3
4
5
6
7
8
9
10
class Animal:
def __init__(self,name,type):
self.name=name
self.type=type

animal=Animal("dog","犬科")

print(animal.name)
print(animal.type)

__init__方法的第一个参数永远是self(类似Java和C++中的this指针)。

如果定义了__init__方法,在定义实例的时候就不能传递空的参数了。

在类中定义方法的时候,第一个参数的是self,其他与正常的方法相同。

访问限制

在类的成员中,需要控制类的访问,在Java或者C++ 使用private,public等来管理成员的访问权限。

在python中,使用两个下划线__来表示私有变量。

如果我们使用动态赋值给对象赋值了一个__name属性,那python会怎么处理?

1
2
3
4
5
6
class Animal:
__name="dog"

a=Animal()
a.__name=2
print(a.__name )

打印的结果是 2

python会把这个变量当成一个普通的变量与内部定义的私有变量不同,可以被正常的访问。

在内部定义的私有变量会被转化成其它名称,具体的名称根据python版本而不同。

在通常的代码中,我们能看到一些_name 等一些单个下划线开头的变量,这中变量是可以正常被访问,但一般不要那么做,可以当成私有变量。

继承和多态


我们定义了一个Animal的类:

1
2
3
4
5
6
7
8
9
class Animal:
def eat(self):
print("eat")

class Dog(Animal):
pass

d=Dog()
d.eat()

d中有了eat方法,是从基类继承而来。

对于python弱类型语言,天生就是多态,也不需要继承关系。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class WorkerA:
def do(self):
print("WorkA Working")

class WorkerB:
def do(self):
print("WorkB Working")


def doWork(obj):
obj.do()

workerA=WorkerA()
workerB=WorkerB()
doWork(workerA)
doWork(workerB)

打印结果:

1
2
WorkA Working
WorkB Working