• py-opp 类(class)


     类的创建

    class 类名:
      pass
    
    class Bar:
    
        def foo(self,arg):          # self ,是传的实例对象,
            print('self:',self,arg)         #因为类属性和方法会分别绑定和返回给实例对象
    
    z1 = Bar()
    print('实例对象:',z1)
    z1.foo(111)
    print('================')
    z2 = Bar()
    print(z2)
    z2.foo(666)
    
    output>>>
    
    实例对象: <__main__.Bar object at 0x000001DAF653CB70>
    self: <__main__.Bar object at 0x000001DAF653CB70> 111
    ================
    <__main__.Bar object at 0x000001DAF653CBE0>
    self: <__main__.Bar object at 0x000001DAF653CBE0> 666
    View Code

    创建方法

    构造方法,__init__(self, arg)
        obj = 类('a1')
    普通方法
        obj = 类(‘xxx’)
        obj.普通方法名()
    class Person:
    
        def __init__(self, name,age):
    
            #构造方法,构造方法的特性, 类名() 自动执行构造方法
            self.n = name
            self.a = age
            self.x = '0'
        def show(self):
            print('%s-%s' %(self.n, self.a))
    stu1 = Person('kevin', 18)
    stu1.show()
    
    stu2 = Person('lemi', 73)
    stu2.show()
    View Code

    面向对象三大特性

    1.封装

    class Bar:
            def __init__(self, n,a):    #通过构造方法封装属性
                self.name = n
                self.age = a
                self.xue = 'o'
                
    b1 = Bar('alex', 123)
        
    b2 = Bar('eric', 456)
        
    View Code


    1.1适用场景

    #给对象封装一些值 如果多个函数中有一些相同参数时,转换成面向对象

    class DataBaseHelper:
        
            def __init__(self, ip, port, username, pwd):
                self.ip = ip
                self.port = port
                self.username = username
                self.pwd = pwd
          
            def add(self,content):
                # 利用self中封装的用户名、密码等   链接数据
                print('content')
                # 关闭数据链接
            
            def delete(self,content):
                # 利用self中封装的用户名、密码等   链接数据
                print('content')
                # 关闭数据链接
            
            def update(self,content):
                # 利用self中封装的用户名、密码等   链接数据
                print('content')
                # 关闭数据链接
                
            def get(self,content):
                # 利用self中封装的用户名、密码等   链接数据
                print('content')
                # 关闭数据链接
    
    s1 = DataBaseHelper('1.1.1.1',3306, 'alex', 'sb')
    View Code

    2.继承

    1、继承
            
            class 父类:
                pass
                
            class 子类(父类):
                pass
                
        2、重写
            防止执行父类中的方法
            
        3、self永远是执行改方法的调用者
    
        4、
           super(子类, self).父类中的方法(...)
           父类名.父类中的方法(self,...)     
          
        5、Python中支持多继承
    
            a. 左侧优先
            b. 一条道走到黑
            c. 同一个根时,根最后执行
    要点
    class F:
    
        def f1(self):
            print('F.f1')
    
        def f2(self):
            print('F.f2')
    
    class S(F):
        def s1(self):
            print('S.s1')
    
        def f2(self):
            # obj
            print('S.f2')
            # super(S, self).f2() # 执行父类(基类)中的f2方法
            # F.f2(self)          # 执行父类(基类)中的f2方法
    """
    
    """
    obj = S()
    obj.s1()
    obj.f2()
    """
    """
    obj = S()
    obj.s1() # s1中的self是形参,此时代指 obj
    obj.f1() # self用于指调用方法的调用者
    """
    
    # obj = S()
    # obj.f2()
    
    """
    class Base:
        def a(self):
            print('Base.a')
    
    
    class F0(Base):
        def a1(self):
            print('F0.a')
    
    class F1(F0):
        def a1(self):
            print('F1.a')
    
    class F2(Base):
        def a1(self):
            print('F2.a')
    
    class S(F1,F2):
        pass
    
    obj = S()
    obj.a()
    View Code

    class A(object):
        def test(self):
            print('from A')
    
    class B(A):
        def test(self):
            print('from B')
    
    class C(A):
        def test(self):
            print('from C')
    
    class D(B):
        def test(self):
            print('from D')
    
    class E(C):
        def test(self):
            print('from E')
    
    class F(D,E):
        # def test(self):
        #     print('from F')
        pass
    f1=F()
    f1.test()
    print(F.__mro__)
    
    output>>>
    from D
    (<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
    View Code

    在子类中调用父类的方法

     内置方法

     元类(metaclass)

     在Python中一切都是对象,类也是对象,是元类的对象,元类就是类的模板。

    在我们平时创建类时,并不是那么简单,会默认执行元类的__init__等几步

    ---- 图片来自银角大王

    class MyType(type):
    
        def __init__(self, what, bases=None, dict=None):
            super(MyType, self).__init__(what, bases, dict)
    
        def __call__(self, *args, **kwargs):
            obj = self.__new__(self, *args, **kwargs)
            self.__init__(obj)
    
    class Foo(object):
    
        __metaclass__ = MyType
    
        def __init__(self, name):
            self.name = name
    
        def __new__(cls, *args, **kwargs):
            return object.__new__(cls)
    
    # 第一阶段:解释器从上到下执行代码创建Foo类
    # 第二阶段:通过Foo类创建obj对象
    obj = Foo('kevin')
    print(obj.name)
    s2

     异常处理

     异常就是程序运行时发生错误的信号(在程序出现错误时,则会产生一个异常,若程序没有处理它,则会抛出该异常,程序的运行也随之终止)

    ---
    while True:
        try:
            # 代码块,逻辑
            inp = input('请输入序号:')
            i = int(inp)
        except Exception as e:
            # e是Exception对象,对象中封装了错误信息
            # 上述代码块如果出错,自动执行当前块的内容
            print(e)
            i = 1
        print(i)
    
    ---异常的捕捉---
    
    def fun():
        ret = 0
        try:
            li = [11, 22]               #一旦有错误,就会捕捉,下面的错误就不执行,不会出来
            li[81]
            int('w3r')
    
        except IndexError as e:         #逐级细分错误分类捕捉
            print('IndexError',e)           #将子异常放在前面,如果Exception在这就包含了所有异常,后面细分就没用了
        except ValueError as e:
            print('ValueError',e)
        except Exception as e:
            print('Exception',e)
        else:                           #前面错误没有捕捉到才会执行这句,因为有的话前面捕捉到就结束啦。可以原来检测前面的捕捉有没有执行。和while-else 是 while 条件不成立才执行else语句
            ret = 1
            print('没有错误。。')
        finally:                        #最后都要执行这句
            print('....')
    
        return ret
    r = fun()
    if r == 0:
        print('500')
    else:
        pass
    
    ---主动抛异常---
    
    try:
        # 主动出发异常
        raise Exception('不过了...')
    except Exception as e:
        print(e)
    
    --运用
    
    def db():
        # return True
        return False
    
    def index():
        try:
            result = db()
            if not result:
                r = open('log','a')          #当数据库返回有错误时,想要写日志,就想要打开文件写,若果主动抛出异常,就可以在下面一起写
                r.write('数据库处理错误')
                # 打开文件,写日志
                #raise Exception('数据库处理错误')         #抛出错误给下面捕捉,写日志就写一个啦
        except Exception as e:
            str_error = str(e)
            print(str_error)
            r = open('log', 'a')
            r.write(str_error)
            # 打开文件,写日志
    
    index()
    ----------自定义异常---------
    class OldBoyError(Exception):
    
        def __init__(self, msg):
            self.message = msg
    
        def __str__(self):
            return self.message
    
    # obj = OldBoyError('xxx')
    # print(obj)
    try:
        raise OldBoyError('我错了...')
    except OldBoyError as e:
        print(e)# e对象的__str__()方法,获取返回
            
    View Code

    断言

    assert 条件,断言,用于强制用户服从,不服从就报错,可捕获,一般不捕获
    print(23) assert 1==2    #不成立,直接报错,不会执行下面的语句 print(456)

    总结try..except

    1. 把错误处理和真正的工作分开来
    2. 代码更易组织,更清晰,复杂的工作任务更容易实现;
    3. 毫无疑问,更安全了,不至于由于一些小的疏忽而使程序意外崩溃了;

    反射

    通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

    class Foo:
        def __init__(self, name,age):
            self.name = name
            self.age = age
    
        def show(self):
            return  "%s-%s " %(self.name,self.age)
        def __int__(self):
            return 123
        def __str__(self):
            return 'uuu'
    obj = Foo('alex', 18)
    r = int(obj) # r = 123
    u = str(obj)
    
    我们知道,可以用obj.name去访问对象的属性name,当b = 'name',obj.b时会报错,不能这样
    那能不能用字符串也能访问里面的属性或方法
    
    这就要用到反射了
    
    func = getattr(obj, 'show')
    print(func)
    r = func()
    print(r)
    
    output>>>
    <bound method Foo.show of <__main__.Foo object at 0x000001FA6205CC88>>
    alex-18 
    
    #是否有某个属性
    print(hasattr(obj, 'name'))
    
    #设置
    setattr(obj, 'k1', 'v1')
    print(obj.k1)         # v1
    
    #删除
    delattr(obj, 'name')
    # obj.name        #已经没有name属性
    
    
    #运用:去什么东西里面获取什么内容
    #获取输入,然后返回值
    inp = input('>>>')
    v = getattr(obj, inp)
    print(v)
    
    Python中一切都是对象,当然也可以对模块进行反射操作
    import s2
    
    
    # r1 = s2.NAME
    # print(r1)
    # r2 = s2.func()
    # print(r2)
    
    r1 = getattr(s2, 'NAME')
    print(r1)
    
    r2 = getattr(s2, 'func')
    result = r2()
    print(result)
    
    cls = getattr(s2, 'Foo')
    print(cls)
    obj = cls()
    print(obj)
    print(obj.name)
    
    --运用--
    import s2
    inp = input('请输入要查看的URL:')
    if hasattr(s2, inp):
        func = getattr(s2, inp)
        result = func()
        print(result)
    else:
        print('404')
    网页的导航栏,选择不同标题返回不同界面
    当反射对象中的方法时,注意返回的是对象方法的地址,外面用一个变量接收后,再变量.()执行才会执行对象中的方法
    s2

    单例模式

    单例,用于使用同一份实例(对象)

    class Foo:
        def __init__(self, name,age):
            self.name = name
            self.age = age
    
    obj = Foo() # obj是Foo的对象,obj也可以叫做Foo类的 实例(实例化)
    obj1 = Foo()
    obj2 = Foo()
    obj3 = Foo()
    平时我们创建对象,都是 对象名=类() 
    这里每个obj对象都是独立的内存地址,然而在某些运用环境下需要使用同一个对象
    能不能创建一个实例后,接下来的实例都用同一份实例(或对象),当然可以啦,就是下面的单例模式
    
    class Foo:
        def __init__(self, name,age):
            self.name = name
            self.age = age
    
        def show(self):
            print(self.name,self.age)
    
    v = None
    
    while True:
        if v:
            v.show()
        else:
            v = Foo('alex', 123)
            v.show()
    刚开始v是None,进入while 循环会创建一个实例,后面调用v实例就不用创建了,直接调用他的方法
    
    高级一点的表现
    class Foo:
    
        __v = None
    
        @classmethod
        def get_instance(cls):
            if cls.__v:
                return cls.__v
            else:
                cls.__v = Foo()
                return cls.__v
    
    # 既然都用单例模式了,就不要在使用 类()去创建实例
    #在Foo内部用,get_instance 类方法创建一个实例,后面调用都是返回的同一个,看看输出就知道(都是同一个内存地址)
    obj1 = Foo.get_instance()
    print(obj1)
    obj2 = Foo.get_instance()
    print(obj2)
    obj3 = Foo.get_instance()
    print(obj3)
    
    >>>output
    <__main__.Foo object at 0x0000016C3FB4C4A8>
    <__main__.Foo object at 0x0000016C3FB4C4A8>
    <__main__.Foo object at 0x0000016C3FB4C4A8>
    s2

    实际运用

      当用户操作数据库操作数据库连接池时,连接池的接口数量是一定的,用户连接只能共用创建好的连接,不能再创建,当连接都被占用,只有等释放后,供下一个用户连接

  • 相关阅读:
    2277 爱吃皮蛋的小明
    zoj2314 经典 无源汇有上下界最大流 并输出可行流
    [置顶] css3 befor after 简单使用 制作时尚焦点图相框
    [置顶] 程序员的奋斗史(二十八)——寒门再难出贵子?
    TaintDroid:智能手机监控实时隐私信息流跟踪系统(四)
    Activity切换效果(overridePendingTransition)
    Activity生命周期,状态保存恢复(经典)
    大二实习使用的技术汇总(上)
    Struts2配置RESULT中TYPE的参数说明
    关于程序动态库链接和运行时搜索路径设置的个人理解
  • 原文地址:https://www.cnblogs.com/wenyule/p/9060612.html
Copyright © 2020-2023  润新知