若想技术精进,当然得把基础知识打得牢牢的。
廖雪峰的官方网站 python3教程,该网站提供的教程浅显易懂,还附带了讲学视频,非常适合初学者正规入门。
以下是通过廖雪峰python官方网站学习的个人查漏补缺。
主要内容包括:1.模块(模块使用/模块安装) 2.面向对象编程 3.类和实例 4.数据封装 5.访问限制 6.继承和多态 7.静态语言VS动态语言 8.获取对象信息 9.实例属性和类属性
1.模块(模块使用/模块安装)
在Python中,一个.py文件就称之为一个模块(Module)。当一个模块编写完毕,就可以被其他地方引用。注意模块名、函数名、变量名,尽量不要与内置函数名字冲突。为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)。
模块使用:import 模块名
1)public:正常的函数和变量名是公开的(public),可以被直接引用。
2)private:类似_xxx和__xxx这样的函数或变量就是非公开的(private),不应该被直接引用。
private函数或变量不应该被别人引用,那它们有什么用呢?外部不需要引用的函数全部定义成private,只有外部需要引用的函数才定义为public。
模块安装:pip install 模块名
2.面向对象编程
面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。
面向过程 与 面向对象:
面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。
面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。
面向对象的程序设计思想:首先考虑对象是什么?其次考虑对象的属性(property)有哪些?
class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
def print_score(self):
print('%s: %s' % (self.name, self.score))
bart = Student('Bart Simpson', 59)##实例化对象
lisa = Student('Lisa Simpson', 87)##实例化对象
bart.print_score()#对象调用其方法
lisa.print_score()#对象调用其方法
数据封装、继承和多态是面向对象的三大特点。
3.类和实例
面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
在Python中,定义类是通过class关键字:
class Student(object):
pass
class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来的,继承的概念我们后面再讲,通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类。
定义好了Student类,就可以根据Student类创建出Student的实例,创建实例是通过类名+()实现的:
>>> bart = Student() #创建Student类的实例
由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。通过定义一个特殊的__init__方法,在创建实例的时候,就把name,score等属性绑上去:
class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
##注意到__init__方法的第一个参数永远是self,表示创建的实例本身。
有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传。
和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,并且,调用时,不用传递该参数。
4.数据封装
在Student类中,每个实例就拥有各自的name和score这些数据。没有必要从外面的函数去访问,可以直接在Student类的内部定义访问数据的函数( 数据封装的本质 ),这样,就把“数据”给封装起来了。
封装的另一个好处是可以给Student类增加新的方法。类是创建实例的模板,而实例则是一个一个具体的对象,各个实例拥有的数据都互相独立,互不影响;方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据;通过在实例上调用方法,我们就直接操作了对象内部的数据,但无需知道方法内部的实现细节。
5.访问限制
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问。
在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量。
有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name。所以,仍然可以通过_Student__name来访问__name变量,但是强烈建议你不要这么干,因为不同版本的Python解释器可能会把__name改成不同的变量名。
6.继承和多态
继承有什么好处?最大的好处是子类获得了父类的全部功能。由于Animial实现了run()方法,因此,Dog和Cat作为它的子类,什么事也没干,就自动拥有了run()方法:
在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是,反过来就不行:Dog可以看成Animal,但Animal不可以看成Dog。
多态的好处就是,当我们需要传入Dog、Cat、Tortoise……时,我们只需要接收Animal类型就可以了,因为Dog、Cat、Tortoise……都是Animal类型,然后,按照Animal类型进行操作即可。
由于Animal类型有run()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run()方法,这就是多态的意思。
7.静态语言 vs 动态语言
****注意****:对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了。
继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写。动态语言(对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子)的鸭子类型特点决定了继承不像静态语言那样是必须的。
8.获取对象信息
1.使用type()
2.使用isinstance()
对于class的继承关系来说,使用type()就很不方便。我们要判断class的类型,可以使用isinstance()函数。
3.使用dir()
如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list。仅仅把属性和方法列出来是不够的,配合getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态。
如果试图获取不存在的属性,会抛出AttributeError的错误。可以传入一个default参数,如果属性不存在,就返回默认值。也可以获得对象的方法。
9.实例属性和类属性
注意:在编写程序的时候,千万不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性。
实例属性属于各个实例所有,互不干扰;
类属性属于类所有,所有实例共享一个属性;
不要对实例属性和类属性使用相同的名字,否则将产生难以发现的错误。