原文链接:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000
感谢廖老师精彩的Python教程,收益良多,感谢感谢!
整理笔记,以备后续复习,第二部分主要是面向对象部分(部分没有整理,以后补充),整理如下,其中大量的单引号是有问题的,由于word直接打的,嫌麻烦,没有都进行修正,请见谅
101、面向对象编程OOP(Object Oriented Programming) 是一种程序设计思想
把对象作为程序基本单元,一个对象包含数据和操作数据的函数
如果你还没有对象,那么是时候选择一种有对象的语言啦~
102、面向对象的设计思想是从自然界中来的,自然界类(Class)和实例(Instance)的概念很自然,果然艺术来源于生活
103、面向对象的三大特点:数据封装、继承和多态
104、类和实例
类是抽象的模板,实例是根据类创建出来的一个个具体“对象”,每个对象都拥有相同的方法,但是各自数据不同
105、类的定义
class Student(object): #class 后面跟类名,Student,通常是大写开头,紧跟着(object),表示类从哪个类继承的,如没有合适的继承类,就用object,所有类最终都会继承object类
106、__init__方法,第一个参数永远是self,表示创建的实例本身,因此,在__init__方法中,可以把各种属性绑定到self
class Student(object):
def __init__(self, name, score): #init前后都是两个下划线
self.name = name
self.score = score
创建实例的时候,需要传入与__init__方法匹配的参数,但是不用传self,Python解释器自己会把实例变量传进去
bart = Student(‘Bart’, 61)
107、和普通函数相比,类中定义的函数只有一点不同,第一个参数永远是实例变量self,且调用的时候不用传递,此外都是一样的
108、数据封装
直接在类的内部定义访问数据的函数,就把“数据”封装起来了。这些封装数据的函数和类本身是关联起来的,我们称之为类的方法
class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
def print_score(self):
print(‘%s score is %d’ % (self.name, self,score))
调用方法的时候,直接在实例变量上调用就好,除了不需要传self,其他一样
bart.print_score()
109、数据封装的好处
数据和逻辑被“封装”起来了,调用容易,且不用知道实现细节
可以给类增加新方法
110、和静态语言不同,Python允许对实例变量绑定任何数据,即两个实例变量,虽然是一个类的不同实例,但拥有的变量名称可能不同
eg:bart.age = 8 #bart就多了个变量名称
111、访问限制
如果让内部属性不被外部访问,可以在属性的名称前加上两个下划线__,就变成了私有变量,只有内部可以访问,外部不能访问,要获取属性,可以增加新的方法如get_score,如果又要允许更改对应的属性,也是增加新的方法如set_score。
之所以这样做,是因为方法中,可以对参数做检查,避免无效参数
112、Python中,变量名类似__xxx___,是特殊变量,是可以直接访问的,不是private变量
113、有时会有一个下划线开头的实例变量名,外部可以访问,但是,约定俗称的规定是,当你看到这样的变量,意思为,“虽然我可以被访问,但请把我看成私有,不要随意访问”
114、__name 也可以通过_Student__name访问,but不要这样
115、Python本身不阻止你干坏事,全靠自觉
116、不要像下面这么搞,并没有改变私有变量,而是加了个新的变量
bart.__name = ‘New Name’
117、注意下or的用法,判断是是male 或 female
if a is ‘male’ or a is ‘female’ 正确
if a in [‘male’, ‘female’] 正确
if a is ‘male’ or ‘female’ 错误
118、继承和多态
定义class的时候可以从现有的class继承,新的class称为子类(SubClass),被继承的称为基类、父类、超类(Base Class、Super Class)
119、继承的好处
子类获得了父类的全部功能
多态:子类可以改进父类的方法,子类有个与父类同名的方法,子类的方法覆盖父类的
120、当我们定义一个class的时候,我们实际定义了一种数据结构,和python自带的数据结构类似,可以用isinstance()判断,子类也是父类的类型
eg:Dog继承Animal,那么Dog的一个实例也是Animal类型的,反过来不行
121、”开闭”原则
对扩展开放:允许新增Animal子类
对修改封闭:不允许修改依赖Animal类型的函数
122、继承树
123、静态语言和动态语言
静态语言,需要传入什么类型,就必须传入这个类型或者子类
动态语言(Python),不一定需要传入对应的类型,只要函数里面调用的方法,你有就行了
这即动态语言的“鸭子类型”,不要求严格的继承体系,一个对象只要“看起来像鸭子,走路像鸭子”,就可以看做鸭子
124、继承可以把父类的所有功能都直接拿过来,不必从零开始
子类可以增加自己特有的方法,也可以把父类不适合的方法覆盖重写
125、type() 判断对象类型
126、判断是否是函数,用types模块中定义的常量
import types
def fn():
pass
type(fn)==types.FunctionType
type(abs)==types.BuiltinFunctionType
type(lambda x:x)==types.LambdaType
type((x for x in range(10)))==types.GeneratorType
127、使用isinstance()
isistance()判断一个对象是否是该类型本身,或者位于该类型的父继承链上
128、使用dir()
获得一个对象的所有属性和方法
129、类似__xxx__的属性和方法都有特殊的用途,如__len__返回长度,如果调用len()函数试图获取一个对象的长度,len()函数内部,会自动调用__len__()
自己写的类,如果想用len(myObj),可以自己写一个__len__()方法
130、把属性和方法列出来后,可以配合getattr() setattr() hasattr()使用
只有不知道对象信息的时候,我们才去获取,如果已经知道了,就直接用就好了
131、实例属性
实例绑定属性通过实例变量或者self变量
class Student(object):
def __init__(self, name):
self.name = name #给实例绑定属性
s = Student(‘Bob’)
s.score = 90 #给实例绑定属性
del s.score #删除实例的属性
132、类属性,直接在class中定义属性,每个实例都可以访问到
class Student(object):
name = ‘Student’ #name 是类属性
print(Student.name) #类属性调用的时候用类名.属性调用
133、实例属性的优先级比类属性高,实例属性会屏蔽掉类属性,所以千万不要给实例属性和类属性用相同的名字
134、Python 里面没有++
详见https://blog.csdn.net/somehow1002/article/details/73744626
135、创建一个class的实例后,可以给实例绑定任何属性和方法,上面有属性的绑定方法,绑定一个方法如下
def set_age(self, age)
self.age = age
from types import MethodType
s.set_age = MethodType(set_age, s)
s.set_age(25)
给一个实例绑定的方法,对另一个实例是不起作用的
136、想让所有实例都可以调用,就给class绑定方法
def set_score(self, score):
self.score = score
Student.set_score = set_score
通常情况下,set_score方法可以直接定义到class中,but动态绑定让你在程序运行过程中动态给class加功能
137、使用__slots__
限制实例的属性或方法,只允许实例添加某些属性或方法
class Student(object):
__slots__ = (‘name’, ‘age’)
这样当实例想要添加不是name 和age时候,会得到AttributeError错误
138、__slots__定义的属性仅对当前的类实例起作用,对继承的子类不起作用
如果子类中也定义__slots__,那么子类允许定义的属性就是自身__slots__加上父类__slots__
139、@property装饰器负责把一个方法变成属性调用
把getter变属性,只需要加上@property即可,@property 本身又创建另一个装饰器@score.setter #其中score是你的方法名,该装饰器可以把setter变成属性
这时,我们就既可以对参数进行检查,又可以简单使用了
只定义getter,不定义setter方法就是一个只读属性
140、多重继承,一个子类可以同时获得多个父类的所有功能
class Bat(Mammal, Flyable):
141、MixIn 主线通常单一继承下来的,需要混入额外的功能,通过多重继承就可以实现,这种设计称为MixIn 因此可以把Flyable 改成 FlyableMixIn
MixIn的目的就是给一个类增加多个功能