Python是一种面向对象(OOP)的语言,面向对象最重要的概念就是类(class)和实例(instance),必须牢记类是抽象的模板,比如整数类型,代表所有整数,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
Python使用class定义一个类,我们以人为例定义一个People类。
class People:
'''
这里是People类的文档
'''
sex = '男' # People类具有性别属性,并且默认是男
def __init__(self, name):
'''
类进行实例化调用此初始化函数
'''
self.name = name
def set_age(self, age):
'''
设置一个人的年龄
'''
self.age = age
def get_age(self):
'''
获取一个人的年龄
'''
函数判断一个类是否具有某属性
return self.age
else:
未设置年龄,请先调用set_age设置年龄')
return None
def get_sex(self):
'''
获取这个人的性别
'''
的性别是' + self.sex)
return self.sex
def speak(self, msg):
'''
让这个人说一句话
'''
说: ' + str(msg))
xiaoming = People('小明') # 实例化类People的一个对象小明
需要详述的是类中函数的参数self。首先明确类和对象两个概念,类表示的抽象,是一个类型,比如我们定义的People类;对象是类的一个实例,比如上面代码的xiaoming,所以在定义类时分为类本身就具有的东西,比如People类的属性sex,另一种在实例化后才有的东西,比如name,age等,而self就是指的实例化后的对象xiaoming。
xiaoming = People('小明') # 实例化类People的一个对象小明
# 调用类本身的属性sex
print(People.sex) # 正常获取性别
# print(People.name) 由于name是实例化才有的属性,该调用出错
print(xiaoming.sex) # 对象是具有类的属性的,正常
# 类中函数具有self的方法都是实例方法,对象才可以正常调用
xiaoming.set_age(29) # 正常设置小明的年龄
#People.set_age(29) # 报错
l 获取与设置属性
xiaoming.age = 20 # 通过实例对象设置年龄
print(xiaoming.age) # 通过实例对象获取年龄
xiaoming.sex = '女' # 通过实例对象设置性别
print(xiaoming.sex) # 通过实例对象获取性别
xiaoming.height = 178 # 给对象新建一个身高属性等于178
print(xiaoming.height) # 获取新建的属性
l 调用对象方法
xm_age = xiaoming.get_age() # 通过对象方法获取年龄
print(xm_age)
xiaoming.speak('我在学习Python')
l 继承
现在已经定义了人这个类,我们想要再具体一点定义出男和女两个类,因为这个类都属于人类,所以可以使用继承,就不用再实现人所共有的属性和方法。
class Man(People):
男'
class Women(People):
女'
xiaohong = Women('小红') # 实例化一个Women小红
xiaohei = Man('小黑') # 实例化一个Man小黑
print(xiaohong.get_sex()) # 调用小红的获取性别方法,由于子类未实现该方法,则会调用父类的
print(xiaohei.get_sex()) # 调用小黑的获取性别方法
print(isinstance(xiaohei, Man)) # 使用isinstance函数判断xiaohei是否是Man的实例
print(isinstance(xiaohei, People)) # 由于Man继承自People,所以xiaohei也是People的实例
print(issubclass(Man, People)) # 使用issubclass判断Man是否是People的子类
此时Man和Women就是继承自People,称为People的子类。使用继承时需注意,调用子类对象的方法时,若子类未实现,则会传递到父类调用父类的方法,而子类若是实现了与父类相同名称的方法,则会调用子类的方法,也就是子类的方法会覆盖父类方法,这种机制称为多态。
l 其他
我们对整数的运算和执行一些内置函数时,就是在调用int类的内部方法。比如str(1)就会调用int.__str__;1 + 1运算就是调用的int.__add__方法,所以我们只要在定义类时实现该方法就可以实现加法运算,以此可以想到其他的运算也是同样原理。我们现在在People末尾加入这两个方法。
# ……
def __add__(self, other):
'''
在对象进行相加操作时可以任意实现
我们使用年龄相加后返回一个新的People对象
'''
if isinstance(other, People):
if hasattr(self, 'age') and hasattr(other, 'age'):
age = self.age + other.age
与' + other.name + '相加对象')
new_people.set_age(age)
return new_people
else:
请检查年龄是否设置')
else:
人不能与非人对象相加')
return None
def __str__(self):
的性别是'+self.sex
if hasattr(self, 'age'):
年龄是' + str(self.age)
return info
xiaozi = People('小紫') # 实例化一个People对象小紫
xiaolan = People('小蓝') # 实例化一个People对象小蓝
#zilan = xiaozi+xiaolan # 作加法,由于没有设置年龄返回空值
xiaozi.set_age(24)
xiaolan.set_age(26)
zilan = xiaozi+xiaolan
print(zilan) # 小紫与小蓝相加对象的性别是男, 年龄是50
对于数学运算,逻辑运算与一些内置函数调用等,在对象内部都可以自定义实现。
算术运算:__add__、__sub__、__mul__、__div__等
比较运算:__lt__、 __gt__等
其他:__str__、__bool__等