对象
定义:
一个基础的类定义
class myClass:
"""这里是类文档注释"""
# 定义一些基本数据成员, 为public
# 这里相当于static变量, 是可以直接通过类名访问的
name = ""
age = 0
# 定义一些私有属性&方法, 为private
__weight = 0
def __privateFun():
#Do something
pass
# 初始化方法, 将在类对象创建时被调用
def __init__(self):
# 执行一些内容
pass
# 然后是一些类方法
def fun1(self):
pass
几个注意点:
-
def
关键字可以定义一个方法, 但必须包含self
参数, 且必须在第一个self参数无需显式传参, 在调用时可忽略
类数据成员 & 对象数据成员:
参考博客:
https://zag666.blog.csdn.net/article/details/105209782
C++中, 类数据成员即为静态数据成员, 需要使用static访问, 而对象数据成员跟随对象绑定
python中:
-
直接定义在类中的数据成员为类数据成员
但这个数据成员与C++的又有些不同, 他可以作为静态数据成员, 被所有类实例访问, 但若有类实例对其进行了修改, 则不会影响到其他类的访问, 修改的类会创建自己的对象数据成员
class my_class(object): value_list = [1, 2] if __name__ == '__main__': class1 = my_class() class2 = my_class() class2.value_list = [3, 4] print(my_class.value_list) print(class1.value_list) print(class2.value_list) print(id(my_class.value_list)) print(id(class1.value_list)) print(id(class2.value_list))
-
使用self修饰的成员为对象数据成员:
无需像C++一样事先声明, 直接在
__init()__
中定义即可, 其范围不局限与__init()__
, 在整个类中均可使用, 并且可被外部访问
继承&派生:
class DerivedClassName(BaseClassName1, BaseClassName2, BaseClassName3):
<statement-1>
.
.
.
<statement-N>
几个注意点:
-
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) if __name__ == '__main__': test = sample("Tim", 25, 80, 4, "Python") test.speak()
-
引用的基类必须与子类在同一个作用域, 即可以被子类访问到
若要引用其他模块中的类, 则可以使用
.
运算符class DerivedClassName(modname.BaseClassName):
方法重载(覆盖):
与C++相似, 在子类中定义一个与基类相同名称的方法会将基类中的方法覆盖, 而后调用子类的该方法, 执行的便是子类中的定义
class Parent: # 定义父类
def myMethod(self):
print ('调用父类方法')
class Child(Parent): # 定义子类
def myMethod(self):
print ('调用子类方法')
c = Child() # 子类实例
c.myMethod() # 子类调用重写方法
类的专有方法:
这玩意算是每个类中隐式调用的方法, 重载之后相当于C++的运算符operator重载
__init__ # 构造函数,在生成对象时调用
__del__ # 析构函数,释放对象时使用
__repr__ # 打印,转换
__setitem__ # 按照索引赋值
__getitem__ # 按照索引获取值
__len__ # 获得长度
__cmp__ # 比较运算
__call__ # 函数调用
__add__ # 加运算
__sub__ # 减运算
__mul__ # 乘运算
__div__ # 除运算
__mod__ # 求余运算
__pow__ # 乘方
例子:
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)
if __name__ == '__main__':
v1 = Vector(2, 10)
v2 = Vector(5, -2)
print(v1 + v2)
Vector (7, 8)