类是模板,而实例则是根据类创建的对象
一、类、实例的创建
1.创建类
(1)、class 关键字定义类,类名首字母大写
(2)、Python3中类基本都会继承于object类
语法格式如下,我们创建一个Circle圆类:
class Circle(object): # 创建类名为Circle的类、继承object类
pass # 此处可添加属性和方法
注意:我们定义的类都会继承于object类,当然也可以不继承object类;两者区别不大,但没有继承于object类使用多继承时可能会出现问题。
2、创建实例
circle1= Circle()
二、类属性、实例属性
1、实例属性
circle1.r = 1 # r为实例属性
circle2.R= 2
print(circle1.r) # 使用 实例名.属性名 可以访问我们的属性
print(circle2.R)
在定义 Circle 类时,可以为 Circle 类添加一个特殊的 __init__() 方法,当创建实例时,__init__() 方法被自动调用为创建的实例增加实例属性
class Circle(object): # 创建Circle类
def __init__(self, r): # 初始化一个属性r(不要忘记self参数,他是类下面所有方法必须的参数)
self.r = r # 表示给我们将要创建的实例赋予属性r赋值
注意:__init__() 方法的第一个参数必须是 self(self代表类的实例,可以用别的名字,但建议使用约定成俗的self),后续参数则可以自由指定,和定义函数没有任何区别。
2、类属性
class Circle(object):
pi = 3.14 # 类属性
def __init__(self, r):
self.r = r
class Circle(object):
pi = 3.14 # 类属性
def __init__(self, r):
self.r = r
circle1 = Circle(1)
circle2 = Circle(2)
print('----未修改前-----')
print('pi=\t', Circle.pi)
print('circle1.pi=\t', circle1.pi) # 3.14
print('circle2.pi=\t', circle2.pi) # 3.14
print('----通过类名修改后-----')
Circle.pi = 3.14159 # 通过类名修改类属性,所有实例的类属性被改变
print('pi=\t', Circle.pi) # 3.14159
print('circle1.pi=\t', circle1.pi) # 3.14159
print('circle2.pi=\t', circle2.pi) # 3.14159
print('----通过circle1实例名修改后-----')
circle1.pi=3.14111 # 实际上这里是给circle1创建了一个与类属性同名的实例属性
print('pi=\t', Circle.pi) # 3.14159
print('circle1.pi=\t', circle1.pi) # 实例属性的访问优先级比类属性高,所以是3.14111
print('circle2.pi=\t', circle2.pi) # 3.14159
print('----删除circle1实例属性pi-----')
输出结果:
----未修改前-----
pi= 3.14
circle1.pi= 3.14
circle2.pi= 3.14
----通过类名修改后-----
pi= 3.14159
circle1.pi= 3.14159
circle2.pi= 3.14159
----通过circle1实例名修改后-----
pi= 3.14159
circle1.pi= 3.14111
circle2.pi= 3.14159
仔细观察我们通过类创建的实例修改的类属性后,通过其他实例访问类属性他的值还是没有改变。其实是通过实例修改类属性是给实例创建了一个与类属性同名的实例属性而已,实例属性访问优先级比类属性高,所以我们访问时优先访问实例属性,它将屏蔽掉对类属性的访问。
我们删除circle1实例的实例属性pi,就能访问该类的类属性了。
print('----删除circle1实例属性pi-----')
del circle1.pi
print('pi=\t', Circle.pi)
print('circle1.pi=\t', circle1.pi)
print('circle2.pi=\t', circle2.pi)
输出结果:
----删除circle1实例属性pi-----
pi= 3.14159
circle1.pi= 3.14159
circle2.pi= 3.14159
区别:类属性:是共有的属性; 实例属性:实例各自拥有;
注意:当实例属性与类属性一样时 通过实例.属性优先获取实例的属性值 其他实例获取到的还是类属性的值, 只有这个实例的属性与类属性冲突时才获取到他创建的实例属性 实例属性优先级高于类属性
类属性的修改要通过类名.属性名修改
三、Python类的实例方法
方法是表明这个类用是来做什么。
在类的内部,使用 def 关键字来定义方法,与一般函数定义不同,类方法必须第一个参数为 self, self 代表的是类的实例(即你还未创建类的实例),其他参数和普通函数是完全一样。
如下我们给圆类 Circle 添加求面积的方法 get_area :
class Circle(object):
pi = 3.14 # 类属性
def __init__(self, r):
self.r = r # 实例属性
def get_area(self):
""" 圆的面积 """
# return self.r**2 * Circle.pi # 通过实例修改pi的值对面积无影响,这个pi为类属性的值
return self.r**2 * self.pi # 通过实例修改pi的值对面积我们圆的面积就会改变
circle1 = Circle(1)
print(circle1.get_area()) # 调用方法 self不需要传入参数,不要忘记方法后的括号 输出 3.14
注意:示例中的 get_area(self) 就是一个方法,它的第一个参数是 self .__init__(self, name)其实也可看做是一个特殊的实例方法。
在方法的内部需要调用实例属性采用 "self.属性名 " 调用。示例中 get_area(self) 对于 pi 属性的引用 Circle.pi 与 self.pi 存在一定区别。
Circle.pi 使用的是类属性 pi,我们通过创建的实例去修改 pi 的值对它无影响。self.pi 为实例的 pi 值,我们通过创建的实例去修改 pi 的值时,由于使用 self.pi 调用的是实例属性,所以 self.pi 是修改后的值。