文章目录
一、OOP
Object Oriended Programming,面向对象编程,是三大编程范式之一。
其他两种分别是结构化编程、函数式编程。
1、什么是面向对象
面向对象,Object Oriended,其实译为以对象为主导 更恰当,因为对象是OOP中的主角,就好像函数式编程中的函数。
2、什么是对象
Python 中,一切皆对象。
一个Python 对象包含三个部分:id(identity 识别码)、type(对象类型)、
value(对象的值)。
对于类和类的实例,value又可以进一步分为属性(attribute)和方法(method)。
3、OO和PO
面向过程(Procedure Oriented) | 面向对象(Object Oriended) | |
---|---|---|
优点 | 性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源 | 易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统 更加灵活、更加易于维护 |
缺点 | 没有面向对象易维护、易复用、易扩展 | 性能比面向过程低 |
适用场景 | 比如单片机、嵌入式开发、 Linux/Unix等一般采用面向过程开发,性能是最重要的因素。 | 系统复杂性高的项目 |
二、类和实例
1、类和实例
类是蓝图,实例(instance)是按蓝图创建出来(实例化)的对象。
2、类属性和实例属性
实例属性一般在__init__()方法中定义。
3、一个简单的例子
class People:
__count = 0 # 类属性
def __init__(self, name, age): # 初始化函数
self.name = name # 实例属性
self.age = age
def speak(self, words):
print(words)
def walk(self):
pass
if ___name__ == '__main__':
A = People('Ez', '20') # 实例化People,并将变量A指向这个实例
4、类的命名
一般采用大驼峰法。如Student、MyClass。
5、一个实例被创建的过程
会经由两步:
__new__(cls) # 构造实例,eg:刚刚烧出来的陶人
__init__(self) # 初始化实例,eg:上色
这两个方法都是顶级父类object
的函数。
如果再在子类中定义,属于函数重写,此时属于实例函数
其中,__new__()
必须有return语句,将新构造出来的的实例返回给__init__()
作为参数。
一个实例创建的例子:
class People:
def __new__(cls, name, age):
print("An instance has been created")
return object.__new__(cls) # 没有return,则__init__()不会被执行
def __init__(self, name, age):
print("An instance is being initialized")
self.name = name
self.age = age
if __name__ == '__main__':
A = People('Ez', '20')
print(A)
输出
An instance has been created
An instance is being initialized
<__main__.People object at 0x000001E717824400>
销毁一个实例对象
__del__
方法称为“析构方法”,用于实现对象被销毁时所需的操作。比如:释放对象
占用的资源,例如:打开的文件资源、网络连接等。
Python 实现自动的垃圾回收(GC,Garbage Collection ),当对象没有被引用时(即引用计数为0),由垃圾回收器自动调用__del__
方法。
我们也可以通过del 语句删除对象,从而保证调用__del__方法。
系统会自动提供__del__方法,一般不需要自定义析构方法。
class Person:
def __del__(self):
print("销毁对象:{0}".format(self))
p1 = Person()
p2 = Person()
del p2
print(p2)
print("程序结束")
运行结果:
销毁对象:<__main__.Person object at 0x02175610>
程序结束
销毁对象:<__main__.Person object at 0x021755D0>
三、类和方法
在类中定义的函数一般称为方法,有别于类外的的普通函数。
类中有3中常见的方法:
1)实例方法(self)
2)类方法(cls)
3)静态方法(可以理解为辅助方法,与类和实例无关,所以不用传参self或cls)。
其实还有一种类方法(见代码),我们暂且称之为第二种类方法。
1、实例方法
实例方法是从属于实例对象的方法。
定义格式:
def 方法名(self [, 形参列表]):
pass
调用格式
实例对象.实例方法([实参列表])
要点:
- 定义实例方法时,第一个参数必须为self。和前面一样,self 指当前的实例对象。
- 调用实例方法时,不需要也不能给self 传参。self 由解释器自动传参。
实例对象调用实例方法的本质:
A.speak("Hola")
# 解释器内部解释为:
People.speak(A, "Hola")
2、类方法
类方法是从属于“类对象”的方法。
类方法通过装饰器@classmethod 来定义,格式如下:
@classmethod
def 类方法名(cls [,形参列表]) :
pass
要点如下:
- 必须加装饰器 @classmethod
- 第一个cls 必须有;cls 指的就是“类对象”本身;
- 调用类方法格式:“类名.类方法名(参数列表)”。参数列表中,不需要也不能给cls 传
值。 - 类方法中访问实例属性和实例方法会导致错误
- 子类继承父类方法时,传入cls 是子类对象,而非父类对象
3、静态方法
Python 中允许定义与“类对象”无关的方法,称为“静态方法”。
“静态方法”和在模块中定义普通函数没有区别,只不过“静态方法”放到了“类的名字空
间里面”,需要通过“类调用”。
静态方法通过装饰器@staticmethod 来定义,格式如下:
@staticmethod
def 静态方法名([形参列表]) :
pass
要点如下:
- @staticmethod 必须位于方法上面一行
- 调用静态方法格式:“类名.静态方法名(参数列表)”。
- 静态方法中访问实例属性和实例方法会导致错误
4、代码测试
class People:
__count = 0
def __init__(self, name, age):
self.name = name
self.age = age
People.__count += 1 # 注意,这里不能使用self.__count,虽然不会报错
# 实例方法
def speak(self, words):
print(words)
# 类方法,操作类相关的属性
@classmethod
def getCount(cls):
print(cls.__count)
# 静态方法
@staticmethod
def test():
print("I am a static method")
# 第二种类方法
def special():
print("I am a special class method")
实例对象调用示例:
实际上,A.special()
时, 在解释器内部是等同于People.special(A)
,所以报异常:TypeError: special() takes 0 positional arguments but 1 was given
类对象调用示例:
四、访问限制
OOP三大特性
封装 (encapsulation)
隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读取和修改的访问级别。
封装途径
封装就是将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“类”,其中数据和函数都是类的成员。
封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,以特定的访问权限来使用类的成员。
大神文章传送
[1] Python中self用法详解
[2] https://www.cnblogs.com/blackmatrix/p/5606364.html
[3] Python中下划线—完全解读