面向对象-- 属性查找顺序以及绑定方法

2023-11-10

面向对象编程思想的本质就是将数据和功能绑定在一起.

对象本质是容器, 其将数据和功能整合在一起, 所以在Python中: 一切皆对象.

对象:

数据与功能的结合体.

类:

种类, 相当于诸多对象共有的特征(数据,功能)

类只描述对象公共的特征, 不同的特征由对象自己描述. ( 所以 类也是对象, 一切皆对象)

类与对象的创建

在代码编程中, 先有类才能有对象. 先定义类, 后产生对象.

定义一个学生类:

class Student:                                             
    # 学生类公共的数据
    school = '清华大学'
    # 学生类公共的功能
    def choose_course(self):
        print('学生选课功能')

类体代码无需调用就会执行 产生类的名称空间>>>. 类体代码在类定义阶段就会执行!

语法结构


class 类名:
    类体代码
1.class是定义类的关键字
2.类名类似于函数名 但是首字母推荐大写 用于区分
3.类体代码就是存放对象公共数据和功能的地方
    数据: 变量名 = 变量值
    功能: 函数

# 查看名称空间的方法>>>:__dict__
# print(Student.__dict__)  # 返回值是一个字典
# print(Student.__dict__['school'])  # 获取类中的属性
# print(Student.__dict__['choose_course'])  # 获取类中的属性
"""类获取数据和功能有一个简便的方式>>>:句点符"""
print(Student.school)
print(Student.choose_course)

"""如何产生对象:类名加括号"""


obj1 = Student()  # 类名加括号就是在产生一个对象
obj2 = Student()
# print(obj1.__dict__, obj2.__dict__)  # {} {}
# print(obj1.school)  # 清华大学
# print(obj2.school)  # 清华大学
# print(obj1.choose_course)  # bound method
# print(obj2.choose_course)  # bound method
print(obj1.school)  # 清华大学
print(obj2.school)  # 清华大学
Student.school = '北京大学'  # Student.__dict__['school'] = '北京大学'  修改名字与值的对应关系
print(obj1.school)  # 北京大学
print(obj2.school)  # 北京大学

属性查找顺序与绑定方法

对象的名称空间里只存放着对象独有的属性,而对象们相似的属性是存放于类中的。对象在访问属性时,会优先从对象本身的__dict__中查找,未找到,则去类的__dict__中查找

对象实例化

该方法就一个功能>>>:给对象添加独有的数据
       

# 学生类
class Student:
    def __init__(self, name, age, gender):
        '''该方法就一个功能>>>:给对象添加独有的数据'''
        self.name = name  # obj.__dict__['name'] = name
        self.age = age  # obj.__dict__['age'] = age
        self.gender = gender  # obj.__dict__['gender'] = gender

    # 学生类公共的数据
    school = '清华大学'

    # 学生类公共的功能
    def choose_course(self):
        print('学生选课功能')


# obj1 = Student()  # 目前对象没有自己独有的属性
# obj2 = Student()  # 目前对象没有自己独有的属性
# print(obj1.__dict__)  # 大白话就是给字典添加键值对
# print(obj2.__dict__)  # 大白话就是给字典添加键值对


'''方案1:逐步给对象添加独有的数据'''

# obj1.__dict__['name'] = 'yietong'  # obj1.name = 'yietong'
# obj1.__dict__['age'] = 22  # obj1.age = 22
# obj1.__dict__['gender'] = 'female'  # obj1.gender = 'female'

# obj2.__dict__['name'] = 'kevin'  # obj2.name = 'kevin'
# obj2.__dict__['age'] = 2  # obj2.age = 28
# obj2.__dict__['gender'] = 'male'  # obj2.gender = 'male'
# print(obj1.__dict__,obj2.__dict__)
# print(obj1.name)  # yietong
# print(obj2.name)  # kevin


'''方案2:将冗余的添加步骤封装成函数'''

# def init(obj,name,age,gender):
#     obj.name = name  # obj.__dict__['name'] = name
#     obj.age = age  # obj.__dict__['age'] = age
#     obj.gender = gender  # obj.__dict__['gender'] = gender
# init(obj1,'yietong',18,'female')
# init(obj2,'kevin',28,'male')
# print(obj1.name)
# print(obj2.name)


'''方案3:简单的封装成函数没有提现出面向对象整合的精髓>>>:将函数写到类中去'''

# obj1 = Student()
# obj2 = Student()
# Student.set_info(obj1,'yietong',22,'female')
# Student.set_info(obj2,'kevin',28,'male')
# print(obj1.name)  # yietong
# print(obj2.name)  # kevin


'''方案4:类中针对给对象创建独有数据的函数名 专门定义了一个固定的方法'''

# obj1 = Student('yietong', 22, 'female')
# obj2 = Student('kevin', 28, 'male')
# print(obj1.__dict__)
# print(obj2.__dict__)


"""
类中的__init__方法会在类产生对象的时候自动执行
类产生对象的具体步骤
    1.先创建一个没有独有数据的空对象  {}
    2.将空对象和类括号内传入的数据一并交给__init__执行
        __init__的第一个参数就是对象本身
            __init__(obj,name,age,gender)
    3.将创建好的对象自动返回
给你提供这种方式能够减少代码的编写

ps:针对括号内第一个形参self其实就是一个普通的变量名而已
只不过该变量名将来专门接收对象的 所以给它起了个固定的名字叫self
"""

绑定方法

在类中定义的函数默认都是绑定给对象使用的
    即对象来调 会自动将对象当做第一个参数传入

class Student:
    school = '清华大学'
    # __init__方法不要自己去调用 
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def func(self):
        print('%s正在调用func方法'%self.name)

    def index(self):
        print('%s正在调用index方法'%self.name)

obj1 = Student('yietong', 22)
# print(obj1)
obj2 = Student('kevin', 28)
# 类调用类中函数 有几个参数就需要传几个参数
# Student.func(123,222)
# 对象调用类中函数  会将当前调用的对象当做第一个参数自动传入
# obj1.func()
# obj2.func()
# print(obj1.func)
# print(obj2.index)
'''所以应该能理解为什么类中所有的函数第一个参数都是self'''

类调用类中的函数, 有几个参数就传几个参数.

对象调用类中的函数, 会将当前调用的对象当作第一个参数自动传入.

类中的函数默认绑定自己.   对象不用默认绑定.

类名+() 产生对象. 类产生的多个对象都可以访问到类中的公共数据和功能. 

动,静态方法

动态方法:

绑定给对象的方法: 1. 类绑定对象,. 类调用绑定给对象的方法:有几个参数就传几个.

                              2. 对象调用绑定给对象的方法,会自动将对象当作第一个参数传入.

绑定给类的方法:   

                                用到了@classmethod方法

                                 类绑定给类的方法,会自动将类当作第一个参数传入.

                                对象调用绑定给类的方法,也会将产生该对象的类自动当作第一个参数传入.

# 动态方法
	1.绑定给对象的方法
  	class Student:
      def run(self):
        prtin(self)
  	# 类调用绑定给对象的方法:有几个参数就需要传几个参数
    Student.run(123)
    # 对象调用绑定给对象的方法:会自动将对象当做第一个参数传入
    obj1.run()
  
  2.绑定给类的方法
  	class Student:
      @classmethod
      def eat(cls):
        prtin(cls)
  	# 类调用绑定给类的方法:会自动将类当做第一个参数传入
    print(Student)  # <class '__main__.Student'>
    Student.eat()  # <class '__main__.Student'>
    # 对象调用绑定给类的方法:也不需要传参 会讲产生该对象的类自动当做第一个参数传入
    obj1.eat()  # <class '__main__.Student'>
    

静态方法

                        @staticmethod

                         普通函数: 无论谁(类/对象)来调,都必须自己传值.

# 静态方法
	class Student:
    	@staticmethod
      def speak(a):
          print(a)
	1.普普通通的函数:无论谁来调 都必须传固定的参数个数
    # 类调用静态方法:要自己传值
    Student.speak(123)
    # 对象调用静态方法:要自己传值
    obj1.speak(321)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

面向对象-- 属性查找顺序以及绑定方法 的相关文章

随机推荐