python3.0 类的推导过程

一 类的推导过程和绑定方法

介绍类 和 对象 的推导
类是什么 ,相同的、公用的功能和数据的集合体
对象是什么,使用数据、功能的主导者,或者叫使用者。

1. 推导一 写一个功能 学生信息 ,加一个学生能够选课的功能

推导1 写一个功能 学生信息 ,加一个学生能够选课的功能
def choose(stu_self):
    print('%s --%s -- %s -- 正在选课'%(stu_self['name'],stu_self['age'],stu_self['gender']))

stu_obj1 ={
    'shcool':'old',
    'name':'zhangsan',
    'age':18,
    'gender':'male',
    'choose':choose
}

stu_obj2 ={
    'shcool':'old',
    'name':'lisi',
    'age':20,
    'gender':'male',
    'choose':choose
}
stu_obj1['choose'](stu_obj1)
stu_obj2['choose'](stu_obj2)

 每一个学生有共同点和不同点,相同点,同一所学校,同一个班级,同一门课程,同一个宿舍,不同点 姓名 年龄 身高 高矮 胖瘦等等
 分析相同的数据,专门放一个名称空间里, 不同的学生设置一个名称空间,这样的话。不用写重复的代码

推导二 相同的数据,专门放一个名称空间里, 不同的学生设置一个名称空间

class Stu_date():  #
    shoocl = 'old'

    def choose(stu_self):
        print('%s --%s -- %s -- 正在选课')


stu_obj1= Stu_date()
stu_obj1.name ='zhangsan'
stu_obj1.age =18
stu_obj1.gender = 'male'

stu_obj2 = Stu_date()

stu_obj2.name ='lisi'
stu_obj2.age =20
stu_obj2.gender = 'male'


思考: 通过上面的代码整合,使用类这个语法把学生1 和学生2 的相同的属性 放到了一个类空间,各个学生对象自己的属性放到了自己的对象空间内。 缩减了相同的代码



疑问: 通过代码能看出 Stu_date 这个类是是什么类型 ,对象stu_obj1 又是什么类型? 类的默认属性 __dict__ "查看对象的属性,元类编程的时候有用"
print(Stu_date.__dict__)
for i in Stu_date.__dict__:
    print(i,Stu_date.__dict__[i])

可以看出来 类的本质也是做了一个字典,对象的stu_obj 也是一个字典把一个个相关的数据存到字典中去。

推导三 如何在对象创建的时候,把对象属性和类属性放到一起去生成。

class Stu_date():  #
    shoocl = 'old'

    def choose(stu_self):
        print('%s --%s -- %s -- 正在选课')



stu_obj1= Stu_date()
stu_obj1.name ='zhangsan'
stu_obj1.age =18
stu_obj1.gender = 'male'

stu_obj2 = Stu_date()

stu_obj2.name ='lisi'
stu_obj2.age =20
stu_obj2.gender = 'male'

初始化 函数 写一个函数,把每个对象的属性直接调用函数生成
class Stu_date():  #
    shoocl = 'old'

    def choose(stu_self):
        print('%s --%s -- %s -- 正在选课')

stu_obj1= Stu_date()
stu_obj2 = Stu_date()
def init(obj,x,y,z):
    obj.name =x
    obj.age =y
    obj.gender =z

init(stu_obj1,'zhangsan','18','male')
init(stu_obj2,'lisi','20','male')



print(stu_obj2.name)
print(stu_obj2.shoocl)

从当前来看, 使用函数来 生成对象的初始化值,还是有些麻烦,再简洁一下代码,
分析代码 ,stu_obj1= Stu_date() 调用类的时候,类生成一个类的空间,把类下面名字放到名称空间内,名称空间的名字为None ,
通过赋值 = 与对象的名建立了关联。
那么在类生成名称空间的时候,能不能给None对象也造一个名称空间,赋值给对象名,
达到 类的属性 和 对象属性,在对象实例化的时候,就产生了。

推导四:如何 把初始化函数塞到类中,并且简化代码

通过 class 的方法 __init__方法把初始化对象的功能 迁移到类的内部来处理,使用shelf关键字 代替对象名,
调用的时候,达到对象属性和类的属性同时创建的效果。

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

    shoocl = 'old'

    def choose(stu_self):
        print('%s --%s -- %s -- 正在选课')

stu_obj1= Stu_date('zhangsan',18,'male')
stu_obj2= Stu_date('li',19,'male')





推导5 绑定方法

推导五:# 通过上面推导
学生对象有了两个属性的空间,自己对象空间和共有数据的类空间 查找优先级 ,对象属性大于类属性,完成了对象空间和类空间的相关联。

class Stu_data():
    def __init__(self,x,y,z): # 对象属性
        self.name = x
        self.age= y
        self.gender=z


    school = 'old'  # 类属性

    def choose(self):  # 类属性
        print('xuan ke....')


stu_obj1 =Stu_data('zhangsan',19,'male')
print(stu_obj1.name)
print(stu_obj1.age)
print(stu_obj1.school)
print(Stu_data.school)  # 类的属性 也是可以直接访问的。

绑定方法

print(stu_obj1.choose)
<bound method Stu_data.choose of <__main__.Stu_data object at 0x00000209B451A6A0>>

类里面放着 共有的数据和函数 ,当对象访问类的函数的时候,显示出来的不是函数,是绑定方法
 绑定方法是什么?  类的函数对对象做的一个引用, 类把函数做成一个遥控器,self是对象名,
 谁来使用这个函数,self就自动变成对象名,跟绑定方法相关联

class Stu_data():
    def __init__(self,x,y,z): # 对象属性
        self.name = x
        self.age= y
        self.gender=z


    school = 'old'  # 类属性

    def choose(self):  # 类属性
        print('xuan ke....')

Stu_data.choose('dsgsfdgfsd') # self 这个参数就是说明 谁都可以来调用。那么谁来调用这个函数,就把对象名传到这里来,那么这个绑定方法的归属就是谁的


类中定义的数据 是直接共享给所有对象使用的,类中定义的函数是绑定给所有对象来调用的
对象.绑定方法() 会把对象当做第一个参数传入。
类.函数(),就是一个函数的玩法,没有自动传参的效果

stu_obj = Stu_data('zhangsna',10,'smale')

print(stu_obj.name)

stu_obj.choose()

  • self,本质上就是一个参数。这个参数是Python内部会提供,其实本质上就是调用当前方法的那个对象。
  • 对象,基于类实例化出来”一块内存“,默认里面没有数据;经过类的 __init__方法,可以在内存中初始化一些数据。

二 类的魔法方法

类的内置方法都是满足某种条件自动触发的,

new  作用创建类的空对象,返回给init,一般是执行object的功能,所以在自定义中可以省略

init 对象初始化的,对象名赋值空对象,创建对象数据,

call方法 对象加括号就是执行call方法。

str 方法,一般使用类的解释或者输出类的功能。

del方法 当前类在全局被删除的时候,被触发的功能,添加 回收资源函数

enter 和 exit 方法一般成对使用,类似于给 装饰器添加功能的意思,with打开文件的就是enter和exit的功能。
数据库查询   设置类 enter方法代码时链接数据库 exit 是和数据库断开,with 类的实例化对象名 as sql_sersion
在with的缩进中,写操作数据库的sql 语句。执行完成后自动关闭数据库。

dict 把对象的属性写入字典。类的推导过程就是根据dict方法推导出来的,dict以字典的形式保存着属性名和属性值,类的dict 也保存的这属性名和属性值和函数名和函数值
既然类本身也是特俗的字典,要想让类也具有字典的功能,就必须添加三个内置方法
setitem  添加字典的设置功能
getitem 添加获取字典值的功能
delitem 添加 删除字典的功能
add   是添加字典的相加的功能 还有 相减 相乘 相除等功能。



作业

  1. 简述面向对象三大特性?

    封装是将相同的数据和功能组合到一个类的名称空间内,提供给对象使用。
    继承是讲多个类中的公共函数提取出来,放到一个基类的方式然后建立关联,方法或者属性的查找优先级,先从对象空间,类空间,父类空间,
     1. 如果类空间有继承多个父类,优先级从左到右查找。
     2.父类空间有多个,且分别继承不同的父类,有两种查找方式,一种是经典类和新式类,在python3中使用新式类,新式类使用C3算法。
    多态是 不关注对象的属性,只关注对象的方法的实现功能,称之为鸭子类型。
    
  2. 将以下函数改成类的方式并调用 :

    def func(a1):   
        print(a1) 
    
    答案:
    class obj_class:
        def __init__(self,aa):
            self.aa = aa
    
    
    
        def func(self,):
            print(self.aa)
    
    
    obj_first= obj_class('123')
    obj_first.func()
    
        
    
  3. 面向对象中的self指的是什么?

    self 代表 一个参数,在通过对象.方法的方式去执行方法时,这个参数会被python自动传递。
    
  4. 以下代码体现 向对象的什么特性?

    class Person(object):
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
    
    
    obj = Person('武沛齐', 18, '男')
    
    # 封装特性,把特数据封装到类中
    
  5. 以下代码体现 向对象的 么特点?

    class Message(object):
        def email(self):
            """
            发送邮件
            :return:
            """
            pass
    
        def msg(self):
            """
            发送短信
            :return:
            """
            pass
    
        def wechat(self):
            """
            发送微信
            :return:
            """
            pass
     # 类的 封装,封装的是同一类的方法
    
  6. 看代码写结果

    class Foo:
        def func(self):
            print('foo.func')
            
    obj = Foo()
    result = obj.func()
    print(result)
    
    
    输出 ----------
    foo.func
    None
    
    
  7. 看代码写结果

    class Base1:
        def f1(self):
            print('base1.f1')
    
        def f2(self):
            print('base1.f2')
    
        def f3(self):
            print('base1.f3')
            self.f1()
    
    
    class Base2:
        def f1(self):
            print('base2.f1')
    
    
    class Foo(Base1, Base2):
        def f0(self):
            print('foo.f0')
            self.f3()
    
    
    obj = Foo()
    obj.f0()
    #########################
    foo.f0
    base1.f3
    base1.f1
    
    
    
    
  8. 看代码写结果:

    class Base:
        def f1(self):
            print('base.f1')
    
        def f3(self):
            self.f1()
            print('base.f3')
    
    
    class Foo(Base):
        def f1(self):
            print('foo.f1')
    
        def f2(self):
            print('foo.f2')
            self.f3()
    
    
    obj = Foo()
    obj.f2()
    
    ##########################
    foo.f2
    foo.f1
    base.f3
    
  9. 补充代码实现

    user_list = []
    while True:
        user = input("请输入用户名:")
        pwd = input("请输入密码:")
        email = input("请输入邮箱:")
        
    """
    # 需求
    1. while循环提示用户输入 : 用户名、密码、邮箱(正则满足邮箱格式)
    2. 为每个用户创建一个个对象,并添加到user_list中。
    3. 当列表中的添加 3个对象后,跳出循环并以此循环打印所有用户的姓名和邮箱
    """
    
    class Name_info():
        def __init__(self, user, pwd, email):
            self.user = user
            self.pwd = pwd
            self.email = email
    
    
    user_list = []
    
    while len(user_list) < 3:
        user = input("请输入用户名:").strip()
        pwd = input("请输入密码:").strip()
        while True:
            email = input("请输入邮箱:").strip()
            if not re.findall('\w.+@\w.+\.[a-z].+', email):
                print('邮箱格式错误,重新添加')
                continue
            break
    
        user = Name_info(user=user, pwd=pwd, email=email)
        user_list.append(user)
    
    for item in user_list:
        print(f'用户名:{item.user}')
        print(f'密码:{item.pwd}')
        print(f'邮件:{item.email}')
    
    
  10. 补充代码:实现 户注册和登录。

    class User:
        def __init__(self, name, pwd):
            self.name = name
            self.pwd = pwd
    
    
    class Account:
        def __init__(self):
            # 用户列表,数据格式:[user对象,user对象,user对象]
            self.user_list = []
    
        def login(self):
            """
            用户登录,输入用户名和密码然后去self.user_list中校验用户合法性
            :return:
            """
            pass
    
        def register(self):
            """
            用户注册,没注册一个用户就创建一个user对象,然后添加到self.user_list中,表示注册成功。
            :return:
            """
            pass
    
        def run(self):
            """
            主程序
            :return:
            """
            pass
    
    
    if __name__ == '__main__':
        obj = Account()
        obj.run()
        
        
        
    解法1 面向过程的思路
    class User:
        def __init__(self, name, pwd):
            self.name = name
            self.pwd = pwd
    
    
    class Account:
        def __init__(self):
            # 用户列表,数据格式:[user对象,user对象,user对象]
            self.user_list = []
    
        def login(self):
            """
            用户登录,输入用户名和密码然后去self.user_list中校验用户合法性
            :return:
            """
            print('欢迎登陆xx平台'.center(60,'#'))
            key_user = input('请输入用户名:')
            key_password = input('请输入密码:')
            name_state = False
    
            for item in self.user_list:
    
                if item.name == key_user and item.pwd == key_password:
    
                    print(f'尊敬的{item.name}用户,欢迎登陆')
                    name_state = True
            if not name_state:
                print('用户不存在,请进行注册')
                self.register()
    
        def register(self):
            """
            用户注册,没注册一个用户就创建一个user对象,然后添加到self.user_list中,表示注册成功。
            :return:
            """
            print('注册xx平台'.center(60, '#'))
            key_user = input('请输入注册用户名:')
            key_password = input('请输入注册密码:')
            obj_name = User(name=key_user,pwd=key_password)
            self.user_list.append(obj_name)
    
    
        def run(self):
            """
            主程序
            :return:
            """
            while True:
                self.login()
    
    if __name__ == '__main__':
        obj = Account()
        obj.run()
    
    解法2  面向对象的思路
    
    class User:
        def __init__(self, name, pwd):
            self.name = name
            self.pwd = pwd
    
    
    class Account:
        def __init__(self):
            # 用户列表,数据格式:[user对象,user对象,user对象]
            self.user_list = []
    
        def login(self):
            """
            用户登录,输入用户名和密码然后去self.user_list中校验用户合法性
            :return:
            """
    
            key_user = input('请输入用户名:')
            key_password = input('请输入密码:')
            name_state = False
    
            for item in self.user_list:
    
                if item.name == key_user and item.pwd == key_password:
    
                    print(f'尊敬的{item.name}用户,欢迎登陆')
                    name_state = True
            if not name_state:
                print('用户不存在,请进行注册')
    
    
        def register(self):
            """
            用户注册,没注册一个用户就创建一个user对象,然后添加到self.user_list中,表示注册成功。
            :return:
            """
            print('注册xx平台'.center(60, '#'))
            key_user = input('请输入注册用户名:')
            key_password = input('请输入注册密码:')
            obj_name = User(name=key_user,pwd=key_password)
            self.user_list.append(obj_name)
            print(f'尊贵的{key_user}用户,注册完成')
    
    
        def run(self):
            """
            主程序
            :return:
            """
            func_dict ={
                '1':{'messages':'登陆','func_name':self.login},
                '2':{'messages':'注册','func_name':self.register},
            }
    
            while True:
                print('欢迎登陆xx平台'.center(60, '#'))
    
                for line in func_dict:
                    print(line, func_dict.get(line).get('messages'))
    
                key_number = input('请选择序号,(退出q/Q)')
    
                if key_number.upper()=='Q':
                    break
                elif key_number in func_dict:
                    func_dict.get(key_number).get('func_name')()
    
                else:
                    print('序号不存在!')
    
    if __name__ == '__main__':
        obj = Account()
        obj.run()
    
    
    
    
posted @ 2022-01-26 22:02  mmszxc  阅读(38)  评论(0)    收藏  举报