• 路飞学城Python-Day19(practise)


    # 特性1.继承;2.多态;3.封装
    # 1.继承的用处:通过继承就可以解决类与类之间的代码冗余关系
    # 2.多态的用处:1.增加了程序的灵活性,以不变应万变,使用者都是同一种形式去调用(func(animal))2.增加了程序的可扩展性
    # 3.封装的用处:1.在接口附加上对该数据操作的限制,以此完成对数据属性操作的严格控制 2.目的是隔离复杂度
    1.面向对象三大特性,各有什么用处,说说你的理解。
    # 类的属性有数据属性和函数属性,类的数据属性是所有对象共享的,类的函数属性是绑定给对象用的
    # 对象的属性:对象是类的实例化
    2.类的属性和对象的属性有什么区别?
    # 1.面向过程:复杂问题流程化进而简单化,但是代码扩展性查,不易维护
    #   面向过程的应用场景:不需要再对代码做任何扩展了,检测脚本
    # 2.面向对象:可扩展性强,面向对象只能解决扩展性,但是软件开发里可扩展性只是一部分,掌握面向对象是开发的一部分
    #   面向对象的应用场景:用户的需求经常发生变化,互联网应用,游戏
    3.面向过程编程与面向对象编程的区别与应用场景
    类和对象的属性都是用字典的形式保存的
    4.类和对象在内存中是如何保存的
    # 绑定到对象的定义:绑定对象的方法,类去访问自己的函数属性的时候就是一个普通的函数,没有自动调用的方式
    # 绑定到对象的调用:绑定给谁,就应该谁来调用就会把调用者当做第一个参数自动传入
    # 特性:绑定给对象就是对象调用,第一个参数是对象名,对象自动传参数,所有的类中的函数属性是默认绑定给对象的
    """
    class Foo:
        def bound(self):
            print('from Foo')
    f = Foo()
    f.bound()
    """
    # -------------------------
    # 绑定到类的定义:在类的内部定义的,被装饰器classmethod修饰的方法
    # 绑定到类的调用:由类来调用(对象也可以调用,不做限制,第一个参数会传类名)
    # 特性:绑定给类就是类使用,但是对象也可以使用,第一个参数是类名
    """
    class Foo:
        @classmethod
        def bound(cls):
            print('%s被绑定到类的函数'%cls)
    f = Foo()
    # f.bound()
    # Foo.bound()
    """
    # -------------------------
    # 非绑定方法的定义:不与类或者对象绑定,没有自动传值,谁都可以用,就相当于普通函数,一点都没有绑定关系
    # 非绑定方法的调用:在类的内部定义的,被装饰器staticmethod修饰的方法
    # 特性:解除绑定以后就是一个普通的函数工具,不自动传参,有几个参数就在调用的时候写几个参数
    """
    class Foo:
        def __init__(self, name):
            self.name = name
    
        def tell(self):
            print('名字是%s' %self.name)
    
        @staticmethod
        def func1(x,y):#self? 不存在的!
            return x+y
    
    f = Foo('panda')
    print(Foo.func1(1,2))
    print(f.func1(1,3))
    """
    5. 什么是绑定到对象的方法、绑定到类的方法、解除绑定的函数、如何定义,如何调用,给谁用?有什么特性
    class A:
        def __getitem__(self, item):
            return self.__dict__.get(item)
        def __setitem__(self, key, value):
            self.__dict__[key] = value
        def __delitem__(self, key):
            del self.__dict__[key]
    # Item系列
    a = A()
    # 设置数据,触发__setitem__内置方法,实现设置属性
    a["key"] = "val"
    print(a.__dict__)
    # 获取数据,触发__getitem__内置方法,实现获取函数返回值
    print(a["key"])
    # 删除数据,触发__delitem__内置方法,实现删除key和value
    del a["key"]
    print(a.__dict__)
    # 【小结】
    # 1.__setattr__:对属性进行赋值或者修改的时候被调用
    # 2.__getattr__:只有在调用属性时且属性不存在的情况下,触发這个函数的执行
    # 3.__delattr__:当删除一个对象的属性值时,会触发delattr的执行
    6.使用实例进行 获取、设置、删除 数据, 分别会触发类的什么私有方法
    # python中的经典类:只出现在python2中,经典类的特征:没有继承object的类以及它的子类都称为经典类
    # python中的新式类:出现在python2和python3中,新式类特征:继承object的类以及它的子类都称为新式类,python3默认继承object
    # 经典类的继承顺序是深度优先(一条路线到底直到object),新式类的继承顺序是广度优先(同级到底,到object前停止)
    7.python中经典类和新式类的区别
    8.如下示例, 请用面向对象的形式优化以下代码
    '''
    def exc1(host,port,db,charset,sql):
        conn=connect(host,port,db,charset)
        conn.execute(sql)
        return xxx
    def exc2(host,port,db,charset,proc_name):
        conn=connect(host,port,db,charset)
        conn.call_proc(sql)
        return xxx
    # 每次调用都需要重复传入一堆参数
    exc1('127.0.0.1',3306,'db1','utf8','select * from tb1')
    exc2('127.0.0.1',3306,'db1','utf8','存储过程的名字')
    '''
    class Mysql:
        def __init__(self):
            self.host = '127.0.0.1'
            self.port = 3306
            self.db = 'db1'
            self.charset = 'utf-8'
    
        def connect(self):
            return '地址%s 端口号%s 数据库名称%s 字符编码%s' % (self.host, self.port, self.db, self.charset)
    
        def execute(self,sql):
            return 'SQL语句%s已经执行' % sql
    
        def call_proc(self,sql):
            return '已保存%s文件'%sql
    
    
    sq = Mysql()
    print(sq.connect())
    print(sq.execute('select * from '))
    print(sq.call_proc('test.txt'))
    View Code
    9.示例1, 现有如下代码, 会输出什么
    class People(object):
        __name = "luffy"
        __age = 18
    p1 = People()
    print(p1.__name, p1.__age)
    # 会报错,在类的执行阶段就会加载代码了,然后看到__name这种代码就会执行封装,变形以后隐藏,实例化的对象不使用特殊方法(a._A__N)是不能执行的
    View Code
    10.示例2, 现有如下代码, 会输出什么:
    class People(object):
    
        def __init__(self):
            print("__init__")
    
        def __new__(cls, *args, **kwargs):
            print("__new__")
            return object.__new__(cls, *args, **kwargs)
    
    People()
    # 输出结果:先打印__new__,再打印__init__
    # 原因分析:定义类后,类会先创建一个空对象(用__new__),然后会加载初始化方法(__init__),最后返回值
    View Code
    11.请简单解释Python中 staticmethod(静态方法)和 classmethod(类方法), 并分别补充代码执行下列方法。
    class A(object):
    
        def foo(self, x):
            print("executing foo(%s, %s)" % (self,x))
    
        @classmethod
        def class_foo(cls, x):
            print("executing class_foo(%s, %s)" % (cls,x))
    
        @staticmethod
        def static_foo(x):
            print("executing static_foo(%s)" % (x))
    
    a = A()
    # 补充代码
    A.class_foo('id')
    a.static_foo('panda')
    # staticmethod(静态方法)就是将类中的函数变成一个普通函数,做成了函数工具,但是不会自动传参,需要多少参数就传多少参数
    # classmethod(类方法)就是指定给类用的方法,对象也是可以用的,第一个参数就是传类名
    View Code
    12.请执行以下代码,解释错误原因,并修正错误
    class Dog(object):
    
        def __init__(self,name):
            self.name = name
    
        @property
        def eat(self):
            print(" %s is eating" %self.name)
    
    d = Dog("ChenRonghua")
    # d.eat()
    # 修改代码
    d.eat
    # 原因解释:property是将类中的函数属性伪装成数据属性(不能传递参数),调用的时候直接就可以使用函数的方式就像,不需要加括号
    View Code
    class Parent(object):
        x = 1
    
    class Child1(Parent):
        pass
    
    class Child2(Parent):
        pass
    
    print(Parent.x, Child1.x, Child2.x)
    # 输出结果 1 1 1 python3的继承遵循广度优先的规则,Child1会先在自己这里找x,没找到,去Parent里找到了,就拿来了,同理Child2
    Child1.x = 2
    print(Parent.x, Child1.x, Child2.x)
    # 输出结果1 2 1 同样遵循广度优先的规则,Parent找到自己的x=1,Child1找到了刚定义的2,Child2没找到,就去Parent里找,找到了1
    Parent.x = 3
    print(Parent.x, Child1.x, Child2.x)
    # 输出结果 3 2 3 广度优先,Parent里原来的x=1变成了x=3,Child1里x=2,Child2里没找到x,去Parent里找到x变化后的x=3
    13.下面这段代码的输出结果将是什么?请解释。
    14.多重继承的执行顺序,请解答以下输出结果是什么?并解释
    class A(object):
        def __init__(self):
            print('A')
            super(A, self).__init__()
    
    class B(object):
        def __init__(self):
            print('B')
            super(B, self).__init__()
    
    class C(A):
        def __init__(self):
            print('C')
            super(C, self).__init__()
    
    class D(A):
        def __init__(self):
            print('D')
            super(D, self).__init__()
    
    class E(B, C):
        def __init__(self):
            print('E')
            super(E, self).__init__()
    
    class F(C, B, D):
        def __init__(self):
            print('F')
            super(F, self).__init__()
    
    class G(D, B):
        def __init__(self):
            print('G')
            super(G, self).__init__()
    
    if __name__ == '__main__':
        g = G()
        f = F()
    # g = G()输出结果:G>>D>>A>>B,广度优先(最后继承object的最后在找)
    # f = F()输出结果:F>>C>>B>>D>>A 广度优先
    View Code
    15.请编写一段符合多态特性的代码.
    import abc
    class People(metaclass=abc.ABCMeta):
        def __init__(self,name):
            self.name = name
        @abc.abstractmethod
        def walk(self):
            pass
    
    class Man(People):
        def walk(self):
            print('%s is walking' % self.name)
    
    class Women(People):
        def walk(self):
            print('%s is running' % self.name)
    
    pa = Man('panda')
    pa.walk()
    pa1 = Women('girl')
    pa1.walk()
    View Code

     16.很多同学都是学会了面向对象的语法,却依然写不出面向对象的程序,原因是什么呢?原因就是因为你还没掌握一门面向对象设计利器,即领域建模,请解释下什么是领域建模,以及如何通过其设计面向对象的程序?

    # 领域建模的三字经方法:找名词、加属性、连关系>>http://www.cnblogs.com/alex3714/articles/5188179.html >>给你个眼神,自己体会
    View Code

     17.请写一个小游戏,人狗大站,2个角色,人和狗,游戏开始后,生成2个人,3条狗,互相混战,人被狗咬了会掉血,狗被人打了也掉血,狗和人的攻击力,具备的功能都不一样。

    # 注意,请按题14领域建模的方式来设计类。
    # 1.找名词  人 狗
    # 2.加属性  人:数据属性:name,health,attack函数属性:hit
    #           狗:数据属性:name,health,attack函数属性:bit
    # 抽象共性:人和狗属于动物:数据属性:name,health,attack
    # 3.加关系
    class Animal:
        def __init__(self,name ,health,attack):
            self.name = name
            self.health = health
            self.attack = attack
    
    class People(Animal):
        def hit(self,enemy):
            enemy.health -= self.attack
    
    class Dog(Animal):
        def bit(self,enemy):
            enemy.health -= self.attack
    
    P1 = People('panda',100,10)
    P2 = People('zombie',120,10)
    D1 = Dog('small_black',50,5)
    D2 = Dog('big_yellow',60,6)
    D3 = Dog('big_white',40,8)
    
    P1.hit(D1)
    print(D1.health)
    View Code
    18.编写程序, 在元类中控制把自定义类的数据属性都变成大写.
    class MyDef(type):
        def __new__(cls, class_name, class_attr, class_dic):
            upper_data = {}
            for k,v in class_dic.items():
                if not callable(v) and not k.startswith('__'):
                    upper_data[k.upper()] = v
                else:
                    upper_data[k] = v
            return type.__new__(cls, class_name, class_attr, upper_data)
    
    class People(metaclass=MyDef):
        time = 'now'
        work = 'weekends'
    
    print(People.__dict__)
    View Code
    20.编写程序, 编写一个学生类, 要求有一个计数器的属性, 统计总共实例化了多少个学生.
    class Student:
        count = 0
        def __init__(self):
            Student.count += 1
        @classmethod
        def counts(cls):
            return cls.count
    s1 = Student()
    print(Student.counts())
    s2 = Student()
    print(Student.counts())
    View Code
    21. 编写程序, A 继承了 B, 俩个类都实现了 handle 方法, 在 A 中的 handle 方法中调用 B 的 handle 方法
    class B:
        def handle(self):
            print('form B')
    
    class A(B):
        def handle(self):
            super().handle()
    
    a = A()
    a.handle()
    View Code
    
    
    Win a contest, win a challenge
  • 相关阅读:
    Cookies的实际存储位置
    搭建Git本地服务器
    在Tomcat中部署war
    Server.xml配置解析
    Tomcat配置详解,配置文件server.xml详解
    将centos7打造成桌面系统
    英语词汇大全
    商场/超市常见英语标识
    商务英语词汇大全
    常用繁体字大全
  • 原文地址:https://www.cnblogs.com/pandaboy1123/p/9323555.html
Copyright © 2020-2023  润新知