类 Class
(一)基本概念
1.1 面向对象:
面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。
1.2 类:
用来描述具有相同的属性和方法的对象的集合。它定义该集合中每个对象所共有的属性和方法。类就是一个模板,模板里可以包含多个函数,函数里实现一些功能。
1.3 对象:
通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。对象是根据模板创建的实例,通过实例对象可以执行类中的函数。
类方法: 类中定义的函数。无须特定的对象实例就能够工作的从属于类的函数。
方法重写: 如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
数据成员: 类变量或者实例变量用于处理类及其实例对象的相关的数据。
1.4 类变量、实例变量
类变量(类属性): 类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体(方法)之外。类变量通常不作为实例变量使用,类变量也称作属性。
实例变量: 定义在方法中的变量,只作用于当前实例的类。
1.5 类对象、实例对象
类对象: 仅支持两个操作:
1:实例化:实例化操作创建该类的实例。
2:属性引用:类名.属性名 的方式引用属性。
实例对象: 类对象实例化的产物。
1.使用类来创建一个真正的对象,这个对象就叫做这个类的一个实例,也叫作实例对象(一个类可以有无数个实例)。
2.仅支持属性引用一个操作:实例对象名.属性名
1.6 属性绑定
属性已存在时,绑定操作会将属性名指向新的对象;
属性名不存在时,则为该对象添加新的属性,后面就可以引用新增属性
1. 类属性绑定:
时间:类定义时 和 运行时任意时间段
2. 实例属性绑定:
时间:类定义时 和 运行时任意时间段
Python实例调用方法时,会将实例对象作为第一个参数传递因此,__init__方法中的self就是实例对象本身
(二) 类的定义
1、定义语法:
class ClassName(object):
.
.
.
2、类的组成:
- 类由三个部分组成
实例属性或者叫对象属性 或简称属性
方法–可理解为在面向过程中定义的函数, 但是首个参数必须是‘self’
类属性–没有前两个那么常用和重要 - 属性——变量
方法——函数
(方法的调用需要绑定到特定的对象上(通过self.
),而函数不需要)
# 实例属性 必须通过初始化或者实例化对象,通过对象去访问,
class Student(object):
def __init__(self, name):
self.name = name
s = Student('Bob')
print(s.name )
# 类属性 不需要实例化对象,直接通过类名访问
class Student(object):
name = 'Student'
print(Student.name)
# 面向对象
# 属性和方法
class Student(object):
# 初始化方法 self指向创建的实例本身
def __init__(self,name,score):
self.name = name
self.score = score
def print_score(self):
print('%s: %s' % (self.name,self.score))
# 实例化对象1
xiaohong = Student('xiaohong',98)
print(id(xiaohong))
# 实例化对象2
xiaobai = Student('xiaobai',81)
print(id(xiaobai))
# 实例化对象3
xiaobai = Student('xiaobai',81)
print(id(xiaobai))
(三) 类的使用
3.1 构造方法:
- 很多类都倾向于将对象创建为有初始状态的。因此类可能会定义一个名为 init() 的特殊方法(构造方法)。
- 类的实例化操作会自动调用 init() 方法。
- init() 方法可以有参数,参数通过 init() 传递到类的实例化操作上。
class Complex:
def __init__(self, realpart, imagpart):
self.r = realpart
self.i = imagpart
x = Complex(3.0, -4.5)
print(x.r, x.i) # 输出结果:3.0 -4.5
3.2 类中定义方法:
第一个参数必须为self,除第一个参数外,类的方法和普通的函数无区别,如可以使用默认参数,可变参数,关键字参数和命名关键字参数等。
3.3 类中调用方法:
在类中调用一个方法,在实例变量上直接调用即可,除了self不用传递,其他参数正常传入。
3.4 类调用实例属性:
1、标准语法: 类对象.属性名——obj.name
2、实例变量是每个实例都独有的数据,而类变量是该类所有实例共享的属性和方法。
class Dog:
dress = "china" ##类属性,每个实例所共享
def __init__(self,name):
self.name = name ##实例属性,每个实例都是独特的
3、类中调用实例属性: self.属性名
4、类外调用实例属性:实例名.实例属性名
注:类中存在__init__方法时,在实例化类时需要传入参数(实例变量的实参),在调用类的方法时也需要传入方法的实参(方法中存在形参时)
3.5 实例属性与类属性的调用关系:
1.类属性就是属于类所有,可以直接用类名.属性名直接调用,类的属性在内存中只有一份。实例属性就是在__init__()方法中初始化的属性;
2.实例属性属于类的对象所有,可以用对象名.属性名的形式进行调用,但是不能用类名.属性名进行调用 。因为实例属性只有在实例创建时,才会初始化创建。
#1.类属性和实例的属性的调用关系
class Person:
country ="china" #类属性
def __init__(self,name,age):
sex ="男" #这不是实例属性,只是变量而已,用对象名.sex调不出来。
self.name = name #实例属性
self.age = age
#创建对象
print(Person.country)
#print(Person.age) 出错,AttributeError: type object 'Person' has no attribute 'age'
p1 = Person("tom",12)
print(p1.country,p1.age,p1.name)
----------结果如下------------------------------------------------------------------------
china
china 12 tom
3.6 实例属性与类属性的修改
类属性只能通过类名.属性才可以修改
如果使用 对象.类属性 = 值 赋值语句,只会 给对象添加一个属性,而不会影响到 类属性的值
3.7 实例属性与类属性的区别
1.最本质的区别是内存中保存的位置不同,分别是类内存空间和实例内存空间
2.类属性在内存中只保存一份,实例属性在每个对象中都要保存一份
(四) 属性引用
4.1 类属性引用:
class Dog:
kind = 'canine'
def tell_kind():
print(Dog.kind) ##涉及作用域
Dog.tell_kind() # Output: canine
4.2 实例属性引用:
1、总是先到实例对象中查找属性,再到类属性中查找属性;
2、属性绑定语句总是为实例对象创建新属性,属性存在时,更新属性指向的对象。
4.3 可变类属性引用:
class Dog:
tricks = []
def __init__(self, name):
self.name = name
def add_trick(self, trick):
self.tricks.append(trick)
d = Dog('Fido')
e = Dog('Buddy')
d.add_trick('roll over')
e.add_trick('play dead')
print(d.tricks) output:# ['roll over', 'play dead']
(五) 访问限制
- 通过”__”两个下划线可以修饰私有变量
- 通过编写get和set方法来修改对象的属性
- Python中没有真正的私有属性和私有方法