• Python 面向对象


    面向对象

    面向对象是一种编程方式,此编程方式的实现是基于对  和 对象 的使用

    如何创建类,方法,对象?

    class Father(): # 创建类
        def __init__(self): # 构造方法(初始化), self = 对象(obj)
            pass
    
        def show(self): # 创建方法
            return None
    
    obj = Father() # 1.创建对象 2. 调用__init__方法
    
    obj.show() # 调用方法
    View Code

    面向对象的三大特征

    1、封装

    封装,就是将内容封装到某个地方,以后再去调用被封装在某处的内容。

    class Father():
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def show(self):
            print(self.name,self.age)
    
    obj = Father("kidd",16)
    obj2 = Father("jim",17)
    View Code

    2、继承
    子类继承父类

    class Father():
        def basketball(self):
            print("I like basketball")
        def tennis(self):
            print("I like tennis")
        def swimming(self):
            print("I don't like swimming")
    
    class Son(Father): # 继承父类
        # 当父亲和儿子都喜欢时
        def basketball(self):
            # super(子类名,self).父类方法
            super(Son,self).basketball() # 调用父类的方法
            print("I like basketball,too")
        def tennis(self):
            Father.tennis(self)
            print("I like tennis,too")
    
        # 当父亲不喜欢,儿子喜欢时
        # 重构
        def swimming(self):
            print("I like swimming")
    
    son = Son()
    son.basketball()
    son.tennis()
    son.swimming()
    
    # 输出
    I like basketball
    I like basketball,too
    I like tennis
    I like tennis,too
    I like swimming
    View Code

    多继承

    class Grandfather():
        def basketball(self):
            print("I like basketball -G")
        def soccer(self):
            print("I like soccer -G")
    
    class Father():
        def basketball(self):
            print("I like basketball -F")
        def tennis(self):
            print("I like tennis -F")
        def swimming(self):
            print("I don't like swimming -F")
    
    class Son(Father,Grandfather):
        pass
    son = Son()
    
    son.soccer() # 儿子找 ---> 没找到 ---> 父亲找 ---> 没找到 ---> 祖父找 ---> 找到了
    
    son.basketball() # 儿子找 ---> 没找到 ---> 父亲找 ---> 找到了
    
    # 多继承特点
    左侧优先
    同一个根时,根最后执行
    View Code

     3、多态

     Pyhon不支持Java和C#这一类强类型语言中多态的写法,但是原生多态

    同时执行多个方法

    就是说执行了子类的方法,又同时执行父类的方法

    super(type[, object-or-type])

    class GrandFather():
        def __init__(self):
            self.show()
        def show(self):
            print("GrandFather -- show")
    
    class Father(GrandFather):
        pass
    
    class Son(Father):
        def __init__(self):
            super(Son,self).__init__()
    
    s = Son()
    View Code

    当然了,我也可以不用super,直接用  类+方法

    什么是字段,方法?

    字段分为:

    普通字段 (执行只能通过对象访问)

    静态字段 (执行 可以通过对象访问 也可以通过类访问)

    class Foo():
        operator = "Kidd" # 静态字段
    
        def __init__(self):
            self.other = "Jim" # 普通字段
    View Code

    方法分为:

    普通方法 (由对象来调用)

    静态方法 (由类直接调用)

    类方法 (由类直接调用)

    class Foo():
        def general(self): # 普通方法
            print("General method")
        
        @staticmethod # 静态方法
        def sta():
            print("Static method")
        
        @classmethod # 类方法
        def cls(cls):
            print("class method")
    View Code

    property()

    第一个参数是方法名,调用 对象.属性 时自动触发执行方法

    第二个参数是方法名,调用 对象.属性 = XXX 时自动触发执行方法

    第三个参数是方法名,调用 del 对象.属性 时自动触发执行方法

    第四个参数是字符串,调用 对象.属性.__doc__ ,此参数是该属性的描述信息

    class Foo:
    
        def get_bar(self):
            return 'wupeiqi'
    
        # *必须两个参数
        def set_bar(self, value):
            return 'set value' + value
    
        def del_bar(self):
            return 'wupeiqi'
    
        BAR = property(get_bar, set_bar, del_bar, '自定义解释')
    
    obj = Foo()
    
    obj.BAR              # 自动调用第一个参数中定义的方法:get_bar
    obj.BAR = "alex"     # 自动调用第二个参数中定义的方法:set_bar方法,并将“alex”当作参数传入
    del Foo.BAR          # 自动调用第三个参数中定义的方法:del_bar方法
    obj.BAE.__doc__      # 自动获取第四个参数中设置的值:description...
    View Code

    成员修饰符

    共有成员

    私有成员, 指无法直接访问,只能间接访问

    class Student():
        def __init__(self):
            self.id = "001" # 共有字段
            self.__name = "Kidd" # 私有字段
        def common(self): # 共有方法
            return self.id
        def __private(self):# 私有方法
            return self.__name
        def callable(self):
            c = self.common()
            p = self.__private() # 间接的访问
            return c,p
    s = Student()
    
    print(s.id) # 001
    print(s.__name) # 报错
    print(s.callable()) # ('001', 'Kidd')
    
    
    只需要在字段,方法前加 __(两个下划线)即可变成私有
    View Code

    特殊成员

    __init__  __call__  __int__  __str__

    class Foo():
        def __init__(self):
            print("init")
        def __call__(self, *args, **kwargs):
            print("call")
        def __int__(self):
            return 123
        def __str__(self):
            return "str"
    f = Foo() # 类调用(),触发__init__方法
    
    f() # 对象调用(),触发__call__方法
    
    print(int(f))# 当对象调用int方法时,它先执行对象中的__int__方法
    
    print(f) # 为什这条语句会直接触发__str__?
    # 因为 print 语句其实是 print(str()) , so---> print(str(f))
    View Code

     obj.__dict__

    class Foo():
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def other(self):
            self.gender = "male"
    f = Foo("Kidd",16)
    dic = f.__dict__ # 将对象中封装的所有内容,通过字典形式返回
    
    print(dic) # {'name': 'Kidd', 'age': 16}
    View Code

    __getitem__  __setitem__  __delitem__

    # 对象[] 的操作
    
    class Foo():
        def __init__(self,name,age):
            self.name = name
            self.age = age
            self.__dic = self.__dict__ # 设置私有成员,获取对象中封装的所有内容
        def __getitem__(self,item): # 查看时,  f["name"]
            return self.__dic[item]
    
        def __setitem__(self, key, value): # 设置时, f["age"] = 17
            self.__dic[key] = value
            
        def __delitem__(self, key): # 删除时,del f["age"]
            self.__dic.pop(key)
    f = Foo("Kidd",16)
    
    value = f["name"]
    
    f["age"] = 17
    
    del f["age"]
    View Code
    class T(object):
        "实现单利"
        def __new__(cls, *args, **kwargs):
            if not hasattr(cls,"_instance"):
                cls._instance = super().__new__(cls)
            return cls._instance
        
        "构造方法"
        def __init__(self,l):
            self.l = l
        
        
        def __getitem__(self, item):
            if item >= 0 :
                for n,i in enumerate(self.l):
                    if n==item:
                        return i
            else:
                l = reversed(self.l)
                for n,i in enumerate(l,1):
                    if n == abs(item):
                        return i
    
        def __setitem__(self, key, value):
            print(key,value)
    
        def __delitem__(self, key):
            print(key)
    
    t = T(list(range(1,11)))
    
    print(t[-1])
    t["l"] = 0
    del t["l"]
    View Code

    __iter___

    class Foo():
        def __iter__(self):
            a = [1,2,3]
            return iter(a)
    
    f = Foo()
    
    for i in f:
        print(i)
    
    # 如果类中有__iter__方法,对象 ---->可迭代对象
    # for 循环类的对象 , 执行类中的__iter__方法 , 取返回值做可迭代对象
    View Code

    异常处理

    AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
    IOError 输入/输出异常;基本上是无法打开文件
    ImportError 无法引入模块或包;基本上是路径问题或名称错误
    IndentationError 语法错误(的子类) ;代码没有正确对齐
    IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
    KeyError 试图访问字典里不存在的键
    KeyboardInterrupt Ctrl+C被按下
    NameError 使用一个还未被赋予对象的变量
    SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
    TypeError 传入对象类型与要求的不符合
    UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
    导致你以为正在访问它
    ValueError 传入一个调用者不期望的值,即使值的类型是正确的
    常用
    ArithmeticError
    AssertionError
    AttributeError
    BaseException
    BufferError
    BytesWarning
    DeprecationWarning
    EnvironmentError
    EOFError
    Exception
    FloatingPointError
    FutureWarning
    GeneratorExit
    ImportError
    ImportWarning
    IndentationError
    IndexError
    IOError
    KeyboardInterrupt
    KeyError
    LookupError
    MemoryError
    NameError
    NotImplementedError
    OSError
    OverflowError
    PendingDeprecationWarning
    ReferenceError
    RuntimeError
    RuntimeWarning
    StandardError
    StopIteration
    SyntaxError
    SyntaxWarning
    SystemError
    SystemExit
    TabError
    TypeError
    UnboundLocalError
    UnicodeDecodeError
    UnicodeEncodeError
    UnicodeError
    UnicodeTranslateError
    UnicodeWarning
    UserWarning
    ValueError
    Warning
    ZeroDivisionError
    更多异常
    # 需要Try的代码
    try:
        pass
    
    # 有异常
    except Exception as e:
        print(e)
    
    # 无异常
    else:
        print("No Exception")
    
    # 不管有没有异常,finally都要执行
    finally:
        print("Try Finish")
    处理异常流程

     自定义异常 与 主动触发异常

    class Except(Exception):
        def __init__(self,error):
            self.error = error
        def __str__(self):
            return self.error
    
    try:
        raise Except("Custom Exception") # 主动触发异常
    
    except Except as e:
        print(e)
    View Code

    断言

    # 如果条件成立,程序继续执行
    # 否则,报错
    assert 1 == 1
    assert 1 == 2
    View Code

    映射

    映射:通过字符串的形式操作对象中的成员,在python中,一切事物皆是对象

    getattr  hasattr  setattr  delattr

    class Foo():
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def __call__(self, *args, **kwargs):
            show = "%s - %s"%(self.name,self.age)
            return show
        def delete(self):
            return "delete"
    
    f = Foo("kidd",16)
    
    # 取字段
    getattr(f,"name")
    # 取方法
    getattr(f,"__call__")
    
    # 字段是否存在
    hasattr(f,"age")
    # 方法是否存在
    hasattr(Foo,"show")
    
    # 设置字段
    setattr(f,"age",17)
    
    # 删除字段
    delattr(f,"name")
    # 删除方法
    delattr(Foo,"delete")
    View Code

    单例模式

    如:让同学展示自己的姓名,年龄

    class Students:
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def __call__(self, *args, **kwargs):
            content = '''自我介绍
            %s -- %s'''%(self.name,self.age)
            return content
    
    s1 = Students("kidd",16)()
    s2 = Students("bob",15)()
    创建多个实例
    import time
    import threading
    import random
    
    
    class Member(object):
        _instance_lock = threading.Lock()
    
        def __init__(self):
            i = random.randint(1, 3)
            print(i)
            time.sleep(i)
    
        @classmethod
        def instance(cls, *args, **kwargs):
            if not hasattr(Member, "_instance"):
                with Member._instance_lock:
                    if not hasattr(Member, "_instance"):
                        Member._instance = Member(*args, **kwargs)
                return Member._instance
    
    def task():
        obj = Member.instance()
        print(obj)
    
    for i in range(5):
        threading.Thread(target=task,).start()
    多线程单例
    class N():
        def __new__(cls, *args, **kwargs):
            if not hasattr(N,'_state'):
                N._state = super().__new__(cls)
            return N._state
        def __init__(self):
            pass
    __new__单例

    单利模式的目的:保证当前内存中仅存在单个实例,避免内存浪费!

    类中的cls,self指的是谁

    cls:类本身

    self:实例化后的对象

    class T(object):
        def __new__(cls, *args, **kwargs):
            if not hasattr(cls,"_instance"): # T=cls,类本身
                cls._instance = super().__new__(cls)
            return cls._instance
        def __init__(self): # t1=self,类实例后的对象
            print(self)
    t1=T()
    t2=T()
    View Code

    其他相关

    isinstance(obj, cls)

     检查是否obj是否是类 cls 的对象

    class Foo:
        def __init__(self):
            pass
    
    f = Foo()
    
    result = isinstance(f,Foo)
    print(result)
    View Code

    issubclass(sub, super)

    检查sub类是否是 super 类的派生类

    class Grandfather:
        pass
    
    class Father(Grandfather):
        pass
    
    class Son(Father):
        pass
    
    issubclass(Son,Father) # True
    issubclass(Son,Grandfather) # True
    View Code
  • 相关阅读:
    java7或java8新特性
    反射中,Class.forName和ClassLoader区别
    &和&&的区别
    JAVA时区问题总结
    索引失效原因及解决索引失效方法
    索引失效的7种情况
    MySQL Explain详解
    java switch
    java 生成注释文档
    spring 获取配置文件的值
  • 原文地址:https://www.cnblogs.com/py-peng/p/10864827.html
Copyright © 2020-2023  润新知