面向对象 - 类与对象-初始化方法-属性查找

一:面向过程 与 面向对象

 

面向过程编程

核心是过程二字,过程是解决问题的步骤,即:先干啥,后干啥

基于该思想写程序就是在 设计一条条的流水线

​ 优点:复杂的问题流程化、进而简单化

​ 缺点:扩展性差

 

面向对象编程

核心是对象二字,对象是一个用来盛放数据与功能的容器

基于该思想写程序就是在 整合程序

​ 优点:进行解耦合,可扩展性强

​ 缺点:编程复杂度高

 

二:面向对象的实现思路

 

1.基础版本

众所周知:面向对象中,对象就是存放数据和功能的容器,用来存放相关的数据。

现在先写一个基础版本的,非面向对象的学生数据和功能。

此时,学生的数据和功能是完全分开的,没有关联的,只有在调用choose函数的时候,才会传入学生的信息。

# 学生的数据
stu_name = 'xxq'
stu_age = 18
stu_gender = 'male'


# 学生的功能
def choose(name, age, gender):
    print(f'学生:{name}正在选课,年龄:{age},性别:{gender}')


choose(stu_name, stu_age, stu_gender)

# 学生:xxq正在选课,年龄:18,性别:male
 

2.基于面向对象的思想进行改写

之前说到,对象就是一个数据和功能的容器,这里把学生的数据和功能放进一个字典里面。

字典里可以以键值对的形式来存放学生的数据,但是函数只能通过调用来实现,所以还是只有一个雏形。

# 学生的功能
def choose(stu_self):
    print(f'学生:{stu_self["name"]}正在选课,年龄:{stu_self["age"]},性别:{stu_self["gender"]}')

# 字典
stu_obj = {
    'name': 'xxq',
    'age': 18,
    'gender': 'male',
    'choose': choose
}

stu_obj["choose"](stu_obj)

# 学生:xxq正在选课,年龄:18,性别:male
 

3.用类来实现

在用类来实现之前,我们需要先来了解一下类和函数调用的区别。

在定义一个函数之后,需要调用它,才会执行函数体的代码。

而类则和函数不同,类体代码会在类定义阶段立刻执行,然后将产生的名字放到类的名称空间中。

函数需要调用
def call():
    print('调用了call函数')

call()
# 调用了call函数
类不需要调用
class Call:
    print('调用了Call类')

# 调用了Call类

现在有三个学生,他们的学校和功能(选课功能)相同,其余的姓名、性别、年龄不同,如果每个对象中都要写上学校和功能,就会出现代码冗余(同样的代码出现多次),因此,可以将他们公共的数据和功能放在同一个容器中,需要用到了就去拿一下即可,这就引入了 类 这个概念。

 

 

例子 1 类的基本使用

class Student:
    # 存放相同的数据
    school = "Tinghua"

    # 存放相同的功能
    def choose(self):
        print("正在选课")


# 实例化3个学生对象
stu_obj1 = Student()
stu_obj2 = Student()
stu_obj3 = Student()

# 赋值学生1的特有数据
stu_obj1.name = "张三"  # 相当于:stu1_obj1.__dict__["name"] = "张三"
stu_obj1.age = 18
stu_obj1.gender = "male"

# 赋值学生2的特有数据
stu_obj2.name = "李四"
stu_obj2.age = 19
stu_obj2.gender = "female"

# 赋值学生3的特有数据
stu_obj3.name = "王五"
stu_obj3.age = 20
stu_obj3.gender = "male"

print(stu_obj1.__dict__)
print(stu_obj2.__dict__)
print(stu_obj3.__dict__)

'''
{'name': '张三', 'age': 18, 'gender': 'male'}
{'name': '李四', 'age': 19, 'gender': 'female'}
{'name': '王五', 'age': 20, 'gender': 'male'}
'''
 

例子 2 初始化方法的引入

之前的用来类的方法来实现的面向对象的思想,进行的数据的整合,把相同的数据和功能放进了一个类中,然后不同的对象再赋不同的值,但是整体看上去还是太麻烦了,每个对象都要单独赋值,也存在很多代码冗余。因此,我们可以定义一个函数init来调用对象中的属性,直接以参数传递的形式来赋值。

class Student:
    # 相同的数据
    school = "oldboy"

    # 相同的功能
    def choose(self):
        print("正在选课")


# 实例化3个对象
stu_obj1 = Student()
stu_obj2 = Student()
stu_obj3 = Student()


# 定义一个函数来调用对象中的属性
def init(obj, x, y, z):
    obj.name = x
    obj.age = y
    obj.gender = z


init(stu_obj1, '张三', 18, 'male')
init(stu_obj2, '李四', 19, 'female')
init(stu_obj3, '王五', 20, 'male')

print(stu_obj1.__dict__)
print(stu_obj2.__dict__)
print(stu_obj3.__dict__)

'''
{'name': '张三', 'age': 18, 'gender': 'male'}
{'name': '李四', 'age': 19, 'gender': 'female'}
{'name': '王五', 'age': 20, 'gender': 'male'}
'''
 

三:初始化方法

 

例子 3 初始化方法的使用

之前的init在类中其实是有一个__init__方法的,可以直接将调用对象作为一个参数自动传入,省去了很多麻烦,只需要传需要的参数就可以了

class Student:
    # 相同的数据
    school = "oldboy"

    def __init__(obj, x, y, z):
        obj.name = x
        obj.age = y
        obj.gender = z
        # return None # 这里如果要加return 只能返回None

    # 相同的功能
    def choose(self):
        print("正在选课")

# 调用类:
# 1.创建一个空对象与类相关
# 2.把空对象、'张三', 18, "male"一起传给__init__方法,完成对象的初始化
# 3.赋值符号把初始化好的对象的内存地址绑定变量名stu_obj1
# 实例化3个对象,并传值
stu_obj1 = Student('张三', 18, "male")
stu_obj2 = Student('李四', 19, "female")
stu_obj3 = Student('王五', 20, "male")

print(stu_obj1.__dict__)
print(stu_obj2.__dict__)
print(stu_obj3.__dict__)

'''
{'name': '张三', 'age': 18, 'gender': 'male'}
{'name': '李四', 'age': 19, 'gender': 'female'}
{'name': '王五', 'age': 20, 'gender': 'male'}
'''
 

四:属性查找

在Python语法中,属性的查找是存在优先级的:先去对象自身找,找不到,再去进行实例化的类中找。

class Student:
    school = 'Tinghua'

stu_obj = Student()
print(stu_obj.school)
# Tinghua

stu_obj.school = 'Peking'
print(stu_obj.school)
# Peking

在上述代码中,定义了一个student类,其中定义了一个变量名school = 'Tinghua'

实例化一个对象stu_obj之后,查找stu_objschool,找到的是Student类中的school,因此输出是Tinghua

而在这之后,又单独给stu_objschool 单独赋值了Peking

因此查找stu_obj'school,找到的是stu_obj对象中的school,因此输出是Peking

 

 

五:绑定方法

类中定义的函数是绑定给所有对象用的,绑定给谁就应该由哪个对象来调用
对象.绑定方法()会把对象当作第一个参数传入
类.函数()就是一个函数的玩法,没有自动传参的效果
class Student:
    school = "oldboy"

    def __init__(obj, x, y, z):
        obj.name = x
        obj.age = y
        obj.gender = z

    def choose(self):
        print("%s 正在选课" % self.name)


stu_obj1 = Student('张三', 18, "male")
stu_obj2 = Student('李四', 19, "female")
stu_obj3 = Student('王五', 20, "male")

print(Student.choose)
print(stu_obj1.choose)
print(stu_obj2.choose)
print(stu_obj3.choose)

'''
<function Student.choose at 0x000001AFAF5A68C8>
<bound method Student.choose of <__main__.Student object at 0x000001AFB6690AC8>>
<bound method Student.choose of <__main__.Student object at 0x000001AFB788B2E8>>
<bound method Student.choose of <__main__.Student object at 0x000001AFB78FB6A0>>
'''
posted @ 2020-08-15 11:44  Οo白麒麟оΟ  阅读(206)  评论(0编辑  收藏  举报