python学习笔记(四)(类和对象)
''' @Author: llody @FilePath: \web\类和对象.py ''' # 在编程领域中,通常把现实世界中的实体称为对象,例如: # 美国总统特朗普 # 中国明星成龙 # 上海中心大厦 # 北京中信大厦 # 这里需要注意的是,对象指的是一个具体的实体,不用于指代一个抽象的群体。例如:特朗普是一个特定的具体的人,可以说 “特朗普是一个对象”。他是一个美国人,因为美国人是一个抽象的概念,指代的是一类人,因此不能说 “美国人是一个对象”。 # 类似的,上海中心大厦、北京中信大厦这些具体的大厦可以被称为对象,但是不使用 “大厦是一个对象” 这样的说法。 #! 1. 对象的属性和行为 # 现实世界中的实体有属性和行为,下面的表格列举了特朗普和成龙的属性和行为: # 对象 属性 行为 # 特朗普 姓名、年龄 自我介绍 # 成龙 姓名、年龄 自我介绍 # 行为又被称为方法,它是对属性的操作,包括读取操作和修改操作。例如,在特朗普的自我介绍行为中,会读取他的属性:姓名和年龄。 #!2.2 对象的属性 string = 'hello world' print(string.__doc__) #打印字符串 ‘Hello world’ 的属性 __doc__,该属性描述了字符串对象的用法 print('================分割线==================') list = ['a','b','c'] print(list.__doc__) #打印列表 list 的属性 __doc__,该属性描述了列表对象的用法 #!2.3 对象的行为 string = 'hello world' print(string.upper()) print(string.lower()) #调用对象的 upper 方法,获取字符串的大写 list = ['a','b','c'] list.append('d') print(list) #调用对象的 append 方法,向列表追加一个元素 #! 3. 什么是类 #! 3.1 类的定义 # 在现实世界中,具体的实体被称为对象,观察这些对象的属性和行为,发现可以使用相同的特征去描述一类对象。例如: # 对象 属性和行为 # 美国总统特朗普 姓名、年龄、工作 # 中国明星成龙 姓名、年龄、工作 # 上海中心大厦 高度、业主、维护 # 北京中信大厦 高度、业主、维护 # 可以使用 “姓名、年龄、工作” 等特征去描述特朗普和成龙这一类对象,使用 “高度、业主、维护” 等特征去描述上海中心大厦、北京中信大厦这一类对象。 # 在编程领域,类是对一组具有相同属性和行为的对象的抽象。例如, “人” 是一个抽象的概念,它是一个类或者类别,描述了具有 “姓名、年龄、工作” 等特征的一组对象;“楼” 是一个抽象的概念,它是一个类或者类别,描述了具有 “高度、业主、维护” 等特征的一组对象。 #! 3.2 类和对象的关系和区别 # 下面的列表总结了类和对象的关系和区别: # 对象是一个具体的实体,例如:特朗普是一个对象 # 类是对多个具有相同属性的实体的抽象,例如:特朗普和成龙等实体具有 “姓名、年龄、工作” 等属性,通过归纳形成一个抽象概念——人,人是一个类 # 对象与类的关系:对象属于某个类、对象不属于某个类,例如:特朗普是一个人,或者说特朗普属于人类 #! 4. Python 中的类 # 本节讲解如何在 Python 中创建类,并利用类来创建对象。首先创建一个具有 name 和 age 两个属性的类——Person,然后利用 Person 这个类创建两个对象—— tom 和 jerry,代码如下: #定义person类 class person: def __init__(self,name,age): self.name = name self.age = age def inter(self): print("我的名字是: %s" %self.name) def upter(self): print("不要骗我哟,我已经:%s" %self.age,'岁了') tom = person('llody',4) tom.inter() tom.upter() #定义一个类person对类中的name和age对象抽象 class Person: #定义了 Person 的方法 introduce,introduce 方法描述了类 Person 的行为 def introduce(self): #!参数 self 指向当前的对象 #类 Person 的 introduce 方法输出 Person 的属性 name 和 age print('My name is %s, I am %d years old' % (self.name, self.age)) #根据类 Person 创建一个新的对象 tom tom = Person() #设置对象 tom 的 name 属性为 ‘tom’ tom.name = 'tom' #设置对象 tom 的 age 属性为 10 tom.age = 10 jerry = Person() jerry.name = 'jerry' jerry.age = 20 #调用对象 tom 的 introduce 方法 tom.introduce() jerry.introduce() #! 总结,在上面的例子中,类和对象分别是: #! Person 是一个类 #! tom 是一个对象 #! jerry 是一个对象 #! Python 类属性和实例属性 # 下表列出了 4 个常见的明星人物: # 姓名 年龄 # 周润发 58 # 成龙 55 # 刘德华 53 # 周星驰 54 # 进行归纳总结: # 这些人物具有较高的知名度,把这些人物归类为明星; # 每个明星两个属性:姓名和年龄。明星这个群体具有一个属性:数量,在这张表格中,明星的数量是 4; # 姓名和年龄等属性是用于描述具体的一个对象(例如:周润发),而人物的数量是用于描述明星这个类别。 # 如果使用面向对象技术对以上实体进行描述,周润发、成龙、刘德华、周星驰等人物是对象,描述这些知名人物的抽象是类,需要区分位于不同层次的属性: # 隶属于具体对象的属性,例如:姓名、年龄 # 隶属于类的属性,例如:人物数量 #! 1. 实例属性 # 实例属性是隶属于具体对象的属性,用于描述具体的对象。 #定义了类 Person class person: def introduce(self): print('My name is %s, I am %d years old' % (self.name, self.age)) #使用类 Person 创建一个对象 zhou zhou = person() #设置对象 zhou 的属性 name,该属性为实例属性 zhou.name = "zhou" #设置对象 zhou 的属性 age,该属性为实例属性 zhou.age = 58 #调用对象 zhou 的方法 introduce,对象 zhou 被传递给方法 introduce,作为 self 参数,在执行 introduce 时,self 参数指向对象 zhou zhou.introduce() #! Python 类的构造方法、析构方法、实例方法 #! 1. 实例方法 # 1.1 定义 #! 实例方法是用于访问对象实例属性的方法 class 类: def 实例方法(self): self.属性 #! 实例方法定义在类中,它的第一个参数 self 指向调用该方法的对象,在实例方法中通过 “self.属性” 访问对象的实例属性。 # 实例方法定义在类中,它的第一个参数 self 指向调用该方法的对象,在实例方法中通过 “self.属性” 访问对象的实例属性。 #! 2. 构造方法 #! 2.1 为什么需要构造方法 #! 在前面的演示实例方法的程序中,创建了两个对象 tom 和 age,创建对象后需要设置属性的初始值 #! 2.2 定义 # 构造方法是用于初始化对象属性的方法,语法如下: class 类: #! 在类中定义了一个方法 __init__,该方法被称为构造方法 # 方法名的前缀和后缀是两个下划线 _ # 方法的第一个参数 self 指向新创建的对象 # 方法的其余参数用于设定对象的属性 def __init__(self, 参数): #在构造方法中,设定初始化对象的属性 self.属性 = 参数 # 使用 “对象 = 类(参数)” 的形式创建一个新的对象,新创建的对象作为 self 参数传递给类的构造方法 __init__ #对象 = 类(参数) class person: def __init__(self,name,age): self.name = name self.age = age def introduce(self): print('名字:%s,年龄:%s' %(self.name,self.age)) tom = person('llody',10) tom.introduce() #! 3. 析构方法 #! 3.1 del 语句 # Python 提供了 del 语句用于删除不再使用的变量,del 语句的语法如下: # del 表达式 # 使用 del 语句删除变量,变量删除后将无法再访问,代码如下: var = 'hello world' print(var) del var #因为变量 var 已经被删除了,所以无法访问变量 var,显示错误:name ‘var’ is not defined #! 3.2 定义 # Python 提供了一种机制使得对象被删除前能够得到通知。对象被删除时,如果该对象拥有名为 __del__ 的方法,该方法在删除前被调用,该方法又被称为析构方法 class 类: #在类中定义了一个方法 __del__,该方法被称为析构方法 def __del__(self): self.属性 # 方法名的前缀和后缀是两个下划线 _ # 方法的参数 self 指向将被删除的对象 #! 3.3 例子 # 创建一个类 Person,并定义析构方法 __del__,然后使用类 Person 创建两个对象,最后再使用 del 语句删除他们,验证析构方法,代码示例如下: class person: #定义了构造方法 __init__ def __init__(self,name,age): self.name = name self.age = age #定义了析构方法 __del__ def __del__(self): print('被del方法删除的是:%s' %self.name) #定义了实例方法 introduce def introduce(self): print('name:%s,age:%s' %(self.name,self.age)) tom = person('llody',10) tom.introduce() #! Python 类的私有属性和私有方法 # 在 Python 的面向对象编程中,私有属性是只能在类的实例方法中访问的属性,不允许在外界访问私有属性。 #! 1. 私有属性的定义 #! 1.1 定义 # 在属性名称前加上前缀 __,表示该属性为私有属性,示例代码如下: class Object: def method(self): #创建一个私有属性 __private_attribute。 self.__private_attribute = 123 #! 1.2 在类外读取私有属性 # 只能在类的实例方法中访问私有属性,不允许在类的外部访问私有属性,示例代码如下: class person: def __init__(self,name): self.__name = name tom = person('llody') #报错:AttributeError:'person' object has no attribute '__name' #print(tom.__name) #!在类 Person 的外部无法直接读取实例的私有属性。 class person: def __init__(self,name): self.__name = name def git_name(self): #要想访问私有属性,就必须使用return返回这个属性 return self.__name tom = person('llody') print(tom.git_name()) #! 1.4 通过 set/get 方法访问私有属性 # 本节在类的外部访问私有属性的方法 class person: def __init__(self,name): self.__name = name #通过实例方法 get_name 读取私有属性 __name def git_name(self): return self.__name #通过实例方法 set_name 修改私有属性 __name def set_name(self,name): self.__name = name tom = person('tom') tom.set_name('jerry') print(tom.git_name()) class person: def __parse(self,word): #通过方法 isdigit 判断是否为数字 if word.isdigit(): print('dig %s' %word) #通过方法 isalpha 判断是否为字母 elif word.isalpha(): print('pha %s' %word) elif word == '=' or word == '+' or word == '*' or word == '-': print('wo %s' %word) def parse (self,string): #使用 split 将文本分割为多个单词 words = string.split(' ') #循环调用私有方法 __parse 处理每个单词 for word in words: self.__parse(word) person = person() #在类 Parser 的外部,调用公开方法 parse person.parse('100 = a * a ') #实现方法 parse 是类 Parser 的接口,外界通过这个方法实现分析文本的功能;而方法 __parse 是一个辅助方法,它用于实现方法 parse,不需要公开给外界调用,因此将它设定为私有方法。 #! Python 类的继承和多继承 # 在面向对象的程序设计中,定义一个新的 class 的时候,可以从某个现有的 class 继承,新的 class 称为子类,而被继承的 class 称为基类、父类或超类。 # Python 中继承的语法如下: #定义了父类 Parent class Parent: pass #定义了子类 Child,语法 Child(Parent) 表示类 Child 继承于类 Parent。 class Child(Parent): pass #!子类继承父类的属性和方法,使得子类具有父类的属性和方法,从而实现代码重用;同时,子类可以增加自己特有的方法。 #! 1. 在子类中增加属性和方法 #! 1.1 编写父类 Person #父类 class person: def __init__(self,name): self.name = name #父类方法 def introduce(self): print('my name is %s' %self.name) #子类继承父类方法 class teacher(person): def __init__(self,name,age): self.name = name self.age = age def show(self): print('my age is %s' %self.age,'yeas old') tom = teacher('llody',10) tom.introduce() tom.show() #子类继承父类方法 class student(person): def __init__(self,name,age,grade): self.name = name self.age = age self.grade = grade def showgrade(self): print('今年:%s ,我读:%s 年级了'%(self.age,self.grade)) toms = teacher('llody',20) toms.introduce() toms.show() tome = student('llody',15,'九') tome.introduce() tome.showgrade() #!在这 子类继承父类的3段初始化代码中,存在明显的代码重复,我们希望:初始类的name,age等重用父类person的代码 class Teacher(person): def __init__(self,name,age,grade): #通过语法 Person.__init(self, name)__ 调用父类的构造方法 __init__,对属性 name 进行设置 person.__init__(self,name) self.age = age self.grade = grade def showGread(self): print('我今年:%s 岁了,我已经:%s年级了'%(self.age,self.grade)) tomo = Teacher('llody',16,'九') tomo.introduce() tomo.showGread() #! 3. 多继承 # 定义一个新的 class 的时候,可以从多个现有的 class 继承,如果继承多个父类,称为多继承。 #父类 class Father: def __init__(self, father_attr): self.father_attr = father_attr def father_method(self): print('father_attr =', self.father_attr) #父类 class Mother: def __init__(self, mother_attr): self.mother_attr = mother_attr def mother_method(self): print('mother_attr =', self.mother_attr) #子类继承两个父类Father,Mother方法 #定义类 Child,继承于 Father 和 Mother class Child(Father, Mother): def __init__(self, father_attr, mother_attr, child_attr): #调用父类 Father 的构造方法 Father.__init__(self, father_attr) #调用父类 Mother 的构造方法 Mother.__init__(self, mother_attr) self.child_attr = child_attr #定义类 Child 的方法 child_method def child_method(self): print('child_attr =', self.child_attr) #创建实例 Child child = Child('Father', 'Mother', 'Child') #调用继承于父类 Father 的方法 father_method child.father_method() #调用继承于父类 Mother 的方法 mother_method child.mother_method() #调用类自己的方法 child_method child.child_method()