作者:韩信子 @ShowMeAI
教程地址:http://www.showmeai.tech/tuto…
本文地址:http://www.showmeai.tech/article-detail/88
申明:版权所有,转载请分割平台与作者并注明出处
1.Python 面向对象
面向对象编程,在英文中称之为 Object Oriented Programming,简称 OOP,是一种程序设计思维。OOP 把对象作为程序的根本单元,一个对象蕴含了数据和操作数据的函数。
Python 是一个纯天然面向对象的编程语言,在 Python 中,所有数据类型都能够视为对象。自定义的对象数据类型就是面向对象中的类(Class)的概念。
2. 面向对象概念
- 类(Class):用来形容具备雷同的属性和办法的对象的汇合。它定义了该汇合中每个对象所共有的属性和办法。对象是类的实例。
- 办法:类中定义的函数。
- 类变量:类变量在整个实例化的对象中是专用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量应用。
- 数据成员:类变量或者实例变量用于解决类及其实例对象的相干的数据。
- 办法重写:如果从父类继承的办法不能满足子类的需要,能够对其进行改写,这个过程叫办法的笼罩(override),也称为办法的重写。
- 局部变量:定义在办法中的变量,只作用于以后实例的类。
- 实例变量:在类的申明中,属性是用变量来示意的,这种变量就称为实例变量,实例变量就是一个用 self 润饰的变量。
- 继承:即一个派生类(derived class)继承基类(base class)的字段和办法。继承也容许把一个派生类的对象作为一个基类对象看待。例如,有这样一个设计:一个 Dog 类型的对象派生自 Animal 类,这是模仿 ” 是一个(is-a)” 关系(例图,Dog 是一个 Animal)。
- 实例化:创立一个类的实例,类的具体对象。
- 对象:通过类定义的数据结构实例。对象包含两个数据成员(类变量和实例变量)和办法。
相比其它编程语言,Python 的类机制十分简洁,Python 中的类提供了面向对象编程的所有基本功能
- 类的继承机制容许多个基类
- 派生类能够笼罩基类中的任何办法
- 办法中能够调用基类中的同名办法
对象能够蕴含任意数量和类型的数据。
3. 类定义
语法格局如下:
class ClassName:
<statement-1>
.
.
.
<statement-N>
类实例化后,能够应用其属性,实际上,创立一个类之后,能够通过类名拜访其属性。
4. 类对象
(1)属性援用和实例化
类对象反对两种操作:属性援用和实例化。
属性援用应用和 Python 中所有的属性援用一样的规范语法:obj.name。
类对象创立后,类命名空间中所有的命名都是无效属性名。所以如果类定义是这样:
class NewClass:
"""一个简略的类实例"""
num = 123456
def f(self):
return 'hello ShowMeAI'
# 实例化类
x = NewClass()
# 拜访类的属性和办法
print("NewClass 类的属性 num 为:", x.num)
print("NewClass 类的办法 f 输入为:", x.f())
以上创立了一个新的类实例并将该对象赋给局部变量 x,x 为空的对象。
执行以上程序输入后果为:
NewClass 类的属性 num 为:123456
NewClass 类的办法 f 输入为:hello ShowMeAI
(2)构造函数
类有一个名为 __init__()
的非凡办法(构造方法 / 构造函数),该办法在类实例化时会主动调用,像上面这样:
def __init__(self):
self.data = []
类定义了 __init__()
办法,类的实例化操作会主动调用 __init__()
办法。如下实例化类 NewClass,对应的 __init__()
办法就会被调用:
x = NewClass()
当然,__init__()
办法能够有参数,参数通过 __init__()
传递到类的实例化操作上。例如(代码能够在在线 python3 环境中运行):
class MyComplex:
def __init__(self, real_part, imag_part):
self.r = real_part
self.i = imag_part
x = MyComplex(5.0, -3.4)
print(x.r, x.i) # 输入后果:5.0 -3.4
(3)self 代表类的实例,而非类
类的办法与一般的函数只有一个特地的区别——它们必须有一个额定的 第一个参数名称, 依照常规它的名称是 self。
class Test:
def prt(self):
print(self)
print(self.__class__)
t = Test()
t.prt()
以上实例执行后果为:
<__main__.Test instance at 0x100724179>
__main__.Test
通过执行后果,能够看出,self 代表的是类的实例(蕴含以后对象的地址信息),而 self.class 则指向类。
留神这里的 self 并不是 python 关键字,把他换成其余名称,比方 showmeai,也是能够失常执行的(代码能够在在线 python3 环境中运行):
class Test:
def prt(showmeai):
print(showmeai)
print(showmeai.__class__)
t = Test()
t.prt()
以上实例执行后果为:
<__main__.Test instance at 0x100724179>
__main__.Test
5. 类的办法
在类的外部,咱们能够应用 def 关键字来定义类办法,类办法必须蕴含参数 self, 且其为第一个参数,self 代表的是类的实例。例如(代码能够在在线 python3 环境中运行)
class Person:
#定义根本属性
name = ''
age = 0
#定义公有属性, 公有属性在类内部无奈间接进行拜访
__weight = 0
#定义构造方法
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def talk(self):
print("%s 的年龄是 %d 岁。" %(self.name,self.age))
# 实例化类
p = Person('ShowMeAI',30,30)
p.talk()
执行以上程序输入后果为:
ShowMeAI 的年龄是 30 岁。
6. 继承
Python 同样反对类的继承。派生类的定义如下所示:
class DerivedClass(BaseClass):
<statement-1>
.
.
.
<statement-N>
子类(派生类 /DerivedClass)会继承父类(基类 /BaseClass)的属性和办法。
BaseClassName(实例中的基类名)必须与派生类定义在一个作用域内。除了类,还能够用表达式,基类定义在另一个模块中时这一点十分有用:
class DerivedClassName(modname.BaseClassName):
# 类定义
class person:
#定义根本属性
name = ''
age = 0
#定义公有属性, 公有属性在类内部无奈间接进行拜访
__weight = 0
#定义构造方法
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def talk(self):
print("%s 的年龄是 %d 岁。" %(self.name,self.age))
#单继承示例
class student(person):
grade = ''
def __init__(self,n,a,w,g):
#调用父类的构函
people.__init__(self,n,a,w)
self.grade = g
#覆写父类的办法
def talk(self):
print("%s 的年龄是 %d 岁,目前在读 %d 年级"%(self.name,self.age,self.grade))
s = student('小 Show',12,60,5)
s.talk()
执行以上程序输入后果为:
小 Show 的年龄是 12 岁,目前在读 5 年级
7. 多继承
Python 同样反对多继承模式。多继承的类定义形如下例:
class DerivedClassName(Base1, Base2, Base3):
<statement-1>
.
.
.
<statement-N>
须要留神圆括号中父类的程序,若是父类中有雷同的办法名,而在子类应用时未指定,python 从左至右搜寻 即办法在子类中未找到时,从左到右查找父类中是否蕴含办法。
# 类定义
class person:
#定义根本属性
name = ''
age = 0
#定义公有属性, 公有属性在类内部无奈间接进行拜访
__weight = 0
#定义构造方法
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 的年龄是 %d 岁。" %(self.name,self.age))
#单继承示例
class student(person):
grade = ''
def __init__(self,n,a,w,g):
#调用父类的构函
people.__init__(self,n,a,w)
self.grade = g
#覆写父类的办法
def talk(self):
print("%s 的年龄是 %d 岁,目前在读 %d 年级"%(self.name,self.age,self.grade))
#另一个类,多重继承之前的筹备
class speaker():
topic = ''name =''
def __init__(self,n,t):
self.name = n
self.topic = t
def talk(self):
print("%s 是一个演说家,明天 ta 演讲的主题是 %s"%(self.name,self.topic))
#多重继承
class sample(speaker,student):
a =''
def __init__(self,n,a,w,g,t):
student.__init__(self,n,a,w,g)
speaker.__init__(self,n,t)
test = sample("ShowMeAI",25,80,4,"Python")
test.talk() #办法名同,默认调用的是在括号中排前地父类的办法
执行以上程序输入后果为:
ShowMeAI 是一个演说家,明天 ta 演讲的主题是 Python
8. 办法重写
如果你的父类办法的性能不能满足你的需要,你能够在子类重写你父类的办法,实例如下:
class Parent: # 定义父类
def my_method(self):
print ('调用父类办法')
class Child(Parent): # 定义子类
def my_method(self):
print ('调用子类办法')
c = Child() # 子类实例
c.my_method() # 子类调用重写办法
super(Child,c).my_method() #用子类对象调用父类已被笼罩的办法
super()函数是用于调用父类 (超类) 的一个办法。
执行以上程序输入后果为:
调用子类办法
调用父类办法
9. 类属性与办法
(1)类的公有属性
__private_attrs
:由两个下划线结尾,申明为公有属性,不能在类的内部被应用或间接拜访。在类外部的办法中能够应用,应用办法为 self.__private_attrs
。
(2)类的办法
在类的外部定义的成员办法,必须蕴含参数 self,且为第一个参数,self 代表的是类的实例。
self 的名字并不是规定死的,也能够应用 this,但倡议还是依照约定应用 self。
(3)类的公有办法
__private_method
:由两个下划线结尾,申明为公有办法,只能在类的外部调用,应用办法为 self.__private_methods
。
类的公有属性示例代码如下:
class NewCounter:
__secret_count = 0 # 公有变量
public_count = 0 # 公开变量
def count(self):
self.__secret_count += 1
self.public_count += 1
print (self.__secret_count)
counter = NewCounter()
counter.count()
counter.count()
print (counter.public_count)
print (counter.__secret_count) # 报错,实例不能拜访公有变量
执行以上程序输入后果为:
1
2
2
Traceback (most recent call last):
File "test.py", line 16, in <module>
print (counter.__secret_count) # 报错,实例不能拜访公有变量
AttributeError: 'NewCounter' object has no attribute '__secret_count'
类的公有办法实例如下:
class WebSite:
def __init__(self, name, url):
self.name = name # public
self.__url = url # private
def who(self):
print('name :', self.name)
print('url :', self.__url)
def __foo(self): # 公有办法
print('这是公有办法')
def foo(self): # 公共办法
print('这是公共办法')
self.__foo()
x = WebSite('ShowMeAI 常识社区', 'www.showmeai.tech')
x.who() # 失常输入
x.foo() # 失常输入
x.__foo() # 报错
(4)类的专有办法:
__init__
:构造函数,在生成对象时调用__del__
:析构函数,开释对象时应用__repr__
:打印,转换__setitem__
:依照索引赋值__getitem__
:依照索引获取值__len__
:取得长度__cmp__
:比拟运算__call__
:函数调用__add__
:加运算__sub__
:减运算__mul__
:乘运算__truediv__
:除运算__mod__
:求余运算__pow__
:乘方
(5)运算符重载
Python 同样反对运算符重载,咱们能够对类的专有办法进行重载,实例如下:
class MyVector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self,other):
return Vector(self.a + other.a, self.b + other.b)
v1 = MyVector(2,10)
v2 = MyVector(5,-2)
print(v1 + v2)
以上代码执行后果如下所示:
Vector(7,8)
10. 视频教程
请点击到 B 站查看【双语字幕】版本
https://www.bilibili.com/vide…
材料与代码下载
本教程系列的代码能够在 ShowMeAI 对应的 github 中下载,可本地 python 环境运行,能迷信上网的宝宝也能够间接借助 google colab 一键运行与交互操作学习哦!
本教程系列波及的 Python 速查表能够在以下地址下载获取:
- Python 速查表
拓展参考资料
- Python 教程—Python3 文档
- Python 教程 - 廖雪峰的官方网站
ShowMeAI 相干文章举荐
- python 介绍
- python 装置与环境配置
- python 根底语法
- python 根底数据类型
- python 运算符
- python 条件管制与 if 语句
- python 循环语句
- python while 循环
- python for 循环
- python break 语句
- python continue 语句
- python pass 语句
- python 字符串及操作
- python 列表
- python 元组
- python 字典
- python 汇合
- python 函数
- python 迭代器与生成器
- python 数据结构
- python 模块
- python 文件读写
- python 文件与目录操作
- python 谬误与异样解决
- python 面向对象编程
- python 命名空间与作用域
- python 工夫和日期
ShowMeAI 系列教程举荐
- 图解 Python 编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解 AI 数学根底:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程