10 类定义、属性、初始化和析构
-
上节课作业解答
mytuple = ('nanbei', 18, 198) mydict = {'name': 'juhao', 'age': 16, 'height': '188'} def exchange1(a, b): return dict(zip(a.keys(), b)), tuple(a.values()) mydict, mytuple = exchange1(mydict, mytuple) print(mydict, mytuple) # 运行结果: {'age': 'nanbei', 'name': 18, 'height': 198} (16, 'juhao', '188')
一,类定义 (使用关键字class)
01 类定义:使用关键字class
02 类属性:变量在类中称为属性,但是类中的属性不仅仅只包含变量,函数等其他的对象也可以作为类的属性
03 类封装: 类可以把各种对象组织在一起,作为类的属性,通过 . (点)运算符来调用类中封装好的对象
(一)简单增加类成员变量
class Person: # 类的定义 var1 = '呵呵' # 直接封装在类中的变量 Person.var2 = '哈哈' # 后来封装在类中的变量 print(Person.var1) print(Person.var2) # 运行结果: 呵呵 哈哈 # 可以看到,在类外部为Person类新增了var2成员变量。
(二)类的实例化
class Person: var1 = '呵呵' p1 = Person() # 实例化 p2 = Person() p1.var1 = 'p1 呵呵' # 用p1直接访问var1 p2.var1 = 'p2 呵呵' print(p1.var1) # 示例中也可看到类中封装的变量 print(p2.var1) print(Person.var1) # 运行结果: p1 呵呵 p2 呵呵 呵呵 # 类属性:在类里面定义的属性,可以通过类和实例访问 # 实例属性:通过实例定义的属性,只能通过实例访问
(三)类的变量,
-
公有变量,形意私有变量(_age),强制私有变量(__height)
class Person: eye = 2 _age = 18 # 私有变量,外部不要访问,强制用也可以用 __height = 188 # 强制成为私有变量,编译器不允许外部访问 print(__height) # 调用双下划线的私有变量 result = Person() print(result._age) print(Person._age) # 可以运行,但不建议 # print(Person.__height) # 报错 print(result._Person__height) # 调用双下划线的私有变量 print(Person._Person__height) # 调用双下划线的私有变量 ''' 在python中有两私有属性,分别是在属性前加 一个下换线(_) 和 两个 下划线(__) _x: 意义在于唤起用户的注意,看成私有属性,类对象和子类可以访问 __xx:双前置下划线,避免与子类中的属性命名冲突,无法在外部直接访问 (名字重整所以访问不到) '''
二,类的方法
-
类方法,实例方法
# 例1 class Person: def eat(): # 类方法定义 print('I am eating!') Person.eat() # 直接调用类方法 # 运行结果: I am eating! # 此时: p = Person() p.eat() # 报错
# 例2 class Person: def eat(self): # 实例方法定义 print('%s正在吃饭。。。' % self.name) p1 = Person() p1.name = '同学A' p1.eat() # 调用实例方法 p2 = Person() p2.name = '同学B' p2.eat() # 运行结果 同学A正在吃饭。。。 同学B正在吃饭。。。 # 此时: Person.eat() # 报错,Person中没有eat属性
-
类方法
eat()
,实例方法eat(self)
-
在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,定义类方法时必须包含参数 self, 且为第一个参数,self 代表的是类的实例。
# 例3 class Person: def eat(self): # 实例方法定义,self 为实例本身 print('%s正在吃饭。。。' % self.name) print(id(self)) p1 = Person() p1.name = '同学A' p1.eat() # 调用实例方法 print(id(p1)) # 运行结果: 同学A正在吃饭。。。 3072556364 3072556364
可见,self 与 p1
内存地址是同一个
三,初始化和析构
(一)类的专有方法(目前无须理解):
方法 | 作用 |
---|---|
__init__ |
构造函数,在生成对象时调用 |
__del__ |
析构函数,释放对象时使用 |
__repr__ |
打印,转换 |
__setitem__ |
按照索引赋值 |
__getitem__ |
按照索引获取值 |
__len__ |
获得长度 |
__cmp__ |
比较运算 |
__call__ |
函数调用 |
__add__ |
加运算 |
__sub__ |
减运算 |
__mul__ |
乘运算 |
__div__ |
除运算 |
__mod__ |
求余运算 |
__pow__ |
乘方 |
(二)魔术方法: __init__(self)
class Person(object): def __init__(self, name, age, height): self.name = name self.age = age self.height = height def eat(self): print('%s正在吃饭...' % self.name) p1 = Person('同学A', 18, 188) p1.eat() print(p1.name) print(p1.age) print(p1.height) # 运行结果: 同学A正在吃饭... 同学A 18 188
-
运行
p1 = Person('同学A', 18, 188)
过程:
注释 | 过程 |
---|---|
实例化,产生一个类的实例 | p1 = Person('同学A', 18, 188) |
python自动调用 实例.__init__(参数) |
p1.__init__('同学A', 18, 188) |
转换为 类.__init__(实例,参数) |
Person.__init__(p1,'同学A', 18, 188) |
(三)析构
_del_ 就是一个析构函数,当使用del删除对象时,会调用他本身的析构函数。提示开发者,对象被销毁了,方便调试。运行以写必要的清理工作。
class Hero(object): def __init__(self,name, HP): self.name = name self.HP = HP def __del__(self): print('%s,被销毁了' % self.name) garen = Hero('盖伦',4000) del garen 运行结果: 盖伦,被销毁了
四,总结
术语 | 定义 |
---|---|
类(Class) | 例如上述 Class Person。用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。 |
类变量 | 类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。 |
数据成员 | 类变量或者实例变量用于处理类及其实例对象的相关的数据。 |
方法重写 | 如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。 |
实例变量 | 定义在方法中的变量,只作用于当前实例的类。 |
继承 | 即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。 |
实例化 | 创建一个类的实例,类的具体对象。 |
方法 | 类中定义的函数。 |
对象 | 通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。 |