声明:由于本人之前学过c++中的类与对象,因此本文中将用c++中的类与对象类比python中的类与对象。这样对于语言的学习有更强的统一性。并且该文中的例子为菜鸟教程中的例子,本文是作者对菜鸟教程中的Python类的教程进行的梳理和解释。
Python中的类与对象:
Python中类与对象的基本语法格式
Python中的类与对象语法格式如下:
class MyClass:
"""一个简单的类实例"""
i = 12345
def f(self):
return 'hello world'
#这里有一个注意点,在类中的函数,函数中如果没有形式参数,那么函数参数中写self,这里的self就是指类的对象,也就是下文中的x
# 实例化类
x = MyClass()
# 访问类的属性和方法
print("MyClass 类的属性 i 为:", x.i)
print("MyClass 类的方法 f 输出为:", x.f())
#输出结果:
#MyClass 类的属性 i 为: 12345
#MyClass 类的方法 f 输出为: hello world
Python类中的函数
Python类中的函数必须有一个额外的第一个参数名称,也就是self,指定为类生成的对象,这是python和c++中类和对象的不同之一。
self代表类的对象,而不是类
class Test:
def prt(self):
print(self)
print(self.__class__)
t = Test()
t.prt()
#运行结果如下:
#<__main__.Test instance at 0x100771878>
#__main__.Test
这里可以明显看出self代表的是类的对象,而非类。
注意:self不是Python的关键词,也就是说Python类中的第一个参数名称可以不叫self。
我们把它换成runoob也是可以的:
class Test:
def prt(runoob):
print(runoob)
print(runoob.__class__)
t = Test()
t.prt()
运行结果和上一个示例相同。
Python的类有一个名为 __init__() 的特殊方法(构造方法)(这不就是c++中的构造函数吗!!!),该方法在类实例化时会自动调用,像下面这样:
def __init__(self):
self.data = []
构造函数会在生成对象时自动运行,和c++中的一样哦。
Python类中的私有公有
Python类中的私有对象以"__"两个下划线为开头,即但凡是两个下划线开头的变量都是私有的,其余的变量都是公有的。
示例:
class JustCounter:
__secretCount = 0 # 私有变量
publicCount = 0 # 公开变量
def count(self):
self.__secretCount += 1
self.publicCount += 1
print (self.__secretCount)
counter = JustCounter()
counter.count()
counter.count()
print (counter.publicCount)
print (counter.__secretCount) # 报错,实例不能访问私有变量
#输出结果为:
#1
#2
#2
#Traceback (most recent call last):
# File "test.py", line 16, in <module>
# print (counter.__secretCount) # 报错,实例不能访问私有变量
#AttributeError: 'JustCounter' object has no attribute '__secretCount'
类中的函数同理:
class Site:
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 = Site('菜鸟教程', 'www.runoob.com')
x.who() # 正常输出
x.foo() # 正常输出
x.__foo() # 报错
Python类中的继承与多重继承
Python中派生类的定义如下:
class DerivedClassName(BaseClassName):
<statement-1>
.
.
.
<statement-N>
可以看到这里可以归纳为:子类(父类)
Python类中的规则其实与c++中的规则大同小异,例如:子类与父类之间的访问权限;子类可以覆写父类中的函数,等等。
单继承的代码示例
Python中的多继承:
class DerivedClassName(Base1, Base2, Base3):
<statement-1>
.
.
.
<statement-N>
即:子类(父类1,父类2,……)
注:如果父类中有相同的函数名,而子类在使用的时候并没有指定使用哪个父类中的函数,则Python默认从左向右在父类中查找。
多继承的代码示例:
#类定义
class people:
#定义基本属性
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(people):
grade = ''
def __init__(self,n,a,w,g):
#调用父类的构函
people.__init__(self,n,a,w)
self.grade = g
#覆写父类的方法
def speak(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 speak(self):
print("我叫 %s,我是一个演说家,我演讲的主题是 %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("Tim",25,80,4,"Python")
test.speak() #方法名同,默认调用的是在括号中参数位置排前父类的方法
#输出结果为:
#我叫 Tim,我是一个演说家,我演讲的主题是 Python
Python类中的一些专有方法
- __init__ : 构造函数,在生成对象时调用
- __del__ : 析构函数,释放对象时使用
- __repr__ : 打印,转换
- __setitem__ : 按照索引赋值
- __getitem__: 按照索引获取值
- __len__: 获得长度
- __cmp__: 比较运算
- __call__: 函数调用
- __add__: 加运算
- __sub__: 减运算
- __mul__: 乘运算
- __truediv__: 除运算
- __mod__: 求余运算
- __pow__: 乘方
Python类中的这些专有方法是用来对运算符进行重载的,因为Python类中并没有像c++一样的operator,所以Python中的运算符重载需要用这些专用方法来进行。
运算符重载的示例如下:
class Vector:
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 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)
#运行结果如下:
#Vector(7,8)