面向对象编程之类和对象的定义
一、两大范式
支持面向对象的语言中,都有两大范式面向过程和面向对象
1、面向过程:流程化、步骤化思维
优点:
复杂的问题简单化,进而流程化
缺点:
扩展性差,牵一发而动全身
使用场景:对扩展性要求不高的地方,一般使用面向过程
2、面向对象
对象就是盛放数据"属性"和"方法"的结合体
属性:简单理解就是变量
方法:简单理解就是函数,或者叫功能
优点:扩展性强
缺点:编程复杂度变高了
使用场景:一般用在对扩展性要求较高的地方
二、
1、类:就是一系列相同属性和相同方法的结合体
2、必须先定义类,然后调用类产生对象
3、定义类发生的几件事情?
- 类一旦被定义,会立马执行类体代码
- 类一旦定义完成,会产生类的名称空间,它会把类中的名字都丢到类的名称空间去
- 会把类的名称空间绑定给__dict__属性, 查看类的名称空间: 类名.__dict__
4、每调用一次类,都会产生一个对象,并且产生的对象之间是相互独立的,互不影响的
5、命名空间存储位置:类的命名空间存储了类的属性和方法。这个命名空间是在内存中的,它是一个字典对象,用于存储类的成员。
三、
stu = Student('zjz', 18, 'male', 9000), Student为类,stu为具体的实例对象。
其中的初始化方法__init__就是为了构造实例对象而存在
class Student: # school就是一个属性 school = 'SH' # 属性就是变量 # __init__这个函数名不能改名字,必须叫这个名字,一点都不能差 def __init__(self, name, age, gender, salary): self.name = name self.age = age self.gender = gender self.salary = salary # 在类里面定义一个方法出来,为什么叫方法了?本质上就是函数,写在类里面就叫方法 def choose_course(self, course, ): self["courses"].append(course) print("%s选择了%s成功,%s" % (self["name"], course, self["courses"])) stu = Student('zjz', 18, 'male', 9000) print(stu.name) # zjz print(stu.age) # 18 print(stu.__dict__) # {'name': 'zjz', 'age': 18, 'gender': 'male', 'salary': 9000}
注⚠️:
1、__init__方法和self:初始化方法,为了构造实例而存在
__init__
是一个特殊的方法,用于在创建类的实例时进行初始化操作。它是类的构造函数,会在对象被创建时自动调用。
调用类会自动的触发类里面的__init__方法,然后会把得到的对象本身当成第一个参数自动传递
例如:
class MyClass: def __init__(self, name, age): self.name = name self.age = age # 创建对象并传递参数 obj = MyClass("Alice", 25) # 访问对象的属性 print(obj.name) # 输出: Alice print(obj.age) # 输出: 25
在上面的例子中,MyClass
类定义了一个__init__
方法,该方法接受两个参数name
和age
。在方法内部,我们使用self.name
和self.age
来将参数值赋给对象的属性。
当我们创建MyClass
的实例obj
时,会自动调用__init__
方法,并将实例对象obj
作为self
参数传递给该方法。这样,obj.name
和obj.age
被赋予了初始值。
__init__
方法在对象创建时执行一次,用于初始化对象的状态。你可以在该方法中执行任何必要的操作,例如设置属性的初始值、打开文件、建立数据库连接等。
需要注意的是,__init__
方法不返回任何值,它仅用于对象的初始化。如果你想为类定义其他的实例方法,可以在类中定义其他的普通方法,这些方法可以使用self
参数来访问对象的属性和方法。
在Python中,每个对象都有一个内置属性__dict__
,它是一个字典,用于存储对象的属性和对应的值。这个字典包含了对象的所有可读和可写的属性。
-
获取对象的属性和值:通过访问对象的
__dict__
属性,可以获取到一个字典,其中包含了对象的所有属性和对应的值。这可以用于动态地检查对象的属性,以及获取或修改对象的属性值。 -
动态添加属性:通过向对象的
__dict__
字典中添加键值对,可以动态地为对象添加新的属性。这在需要在运行时根据需求添加属性时非常有用。 -
动态获取属性:通过访问对象的
__dict__
字典,可以根据属性名称动态地获取属性的值。这对于需要根据变量或用户输入来获取属性值的情况非常有用。 -
序列化和反序列化:
__dict__
属性在对象的序列化和反序列化过程中起着重要的作用。可以将对象的__dict__
字典转换为JSON、pickle等格式,以便将对象保存到文件或通过网络传输,并在需要时重新构造对象。
print(stu.__dict__)
四、
1、 属性的查找顺序分两大类:
类属性:在类里面定义的属性就是类属性
对象属性:就是对象自己独有的属性
# 增加属性 stu.work = 'no job , is student' # 查 # print(stu.work) # 改属性 stu.work = 'ops' # print(stu.work) # 删除 del stu.work del stu.school print(stu.school) # AttributeError: school,实例对象不能删除类中的属性
3、类的增删改查
# 增加属性 Student.work = 'no job , is student' print(Student.work) # 改属性 Student.work = 'ops' print(Student.work) # 删除 del Student.work print(Student.work)
五、函数和方法
from types import MethodType, FunctionType # 函数和方法 # 普通函数,调用时候,有几个值,就要传几个值 # 方法:定义在类内部:对象的绑定方法,类的绑定方法----》绑定给谁,谁来调用---》调用的时候,会自动传值 # 类调用对象绑定方法,就变成了普通函数,有几个值就要传几个值 # 对象调用类的绑定方法,就是方法,会自动传值 # 一切皆对象,函数也是个对象, 由某个类产生 FunctionType def add(): pass print(isinstance(add, FunctionType)) # 判断一个对象是不是这个类的对象 print(isinstance(add, MethodType)) # 判断一个对象是不是这个类的对象 class Foo: def run(self): pass @classmethod def xx(cls): pass @staticmethod def zz(): pass # 对象调用 run ,run就是方法 会自动传值 f=Foo() print(isinstance(f.run,FunctionType)) print(isinstance(f.run,MethodType)) # 类来调用run,run就是函数,有几个值就要传几个值 print(isinstance(Foo.run,FunctionType)) print(isinstance(Foo.run,MethodType)) # 类调用类的绑定方法---》就是方法 print(isinstance(Foo.xx,FunctionType)) print(isinstance(Foo.xx,MethodType)) # 对象调用类的绑定方法---》 也是方法 print(isinstance(f.xx,FunctionType)) print(isinstance(f.xx,MethodType)) # 对象来调用 print(isinstance(f.zz,FunctionType)) # True print(isinstance(f.zz,MethodType)) #False # 类来调用 print(isinstance(Foo.zz,FunctionType)) # True print(isinstance(Foo.zz,MethodType)) #False
注意:
1、借助isinstance(MethodType or FunctionType)判断是函数还是方法
2、类调用对象的方法就是普通函数,有几个参数就要传几个值
3、类和对象调用静态方法其实都是调用函数,有几个参数就要传几个值
4、对象调用类的方法,也还是方法,python自动将对象以类名作为参数传入
六、练习题
定义一个类,产生一堆对象
定义一个计数器,记录产生了多少个对象
# 定义一个类 class Student: school = 'sh' count = 0 # 初始化方法 def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender Student.count += 1 # 关键,属性定成类中的count,每初始化一次count+1 # 调用类产生一堆对象 stu = Student("kevin", 18, 'male') stu1 = Student("kevin1", 18, 'male') stu2 = Student("kevin2", 18, 'male') stu3 = Student("kevin3", 18, 'male') print(stu.__dict__) # 计数器,记录产生多少个对象 print(Student.count)