1. 程式人生 > >Python 抽象篇:面向對象之高階

Python 抽象篇:面向對象之高階

都是 open 全局變量 模塊 超出 無法 ssa ctrl+ elf

1.檢查繼承

如果想要查看一個類是否是另一個類的子類,可以使用內建的issubclass函數

如果想知道已知類的基類,可以直接使用特殊特性__bases__

同時,使用isinstance方法檢查一個對象是否是一個類的實例(instance)

如果想知道一個對象屬於哪個類,可以使用__class__特性

技術分享

2.反射

python中的反射功能是由以下四個內置函數提供:hasattr、getattr、setattr、delattr,改四個函數分別用於對對象內部執行:檢查是否含有某成員、獲取成員、設置成員、刪除成員。

class Foo:
    def __init__(self,name,age):
        self.name
=name self.age=age def show(self): return "%s-%s"%(self.name,self.age) obj=Foo(greg,18) print(obj.name) #greg b="name" print(obj.__dict__) #{‘name‘: ‘greg‘, ‘age‘: 18} print(obj.__dict__[name])#greg print(obj.__dict__[b])#greg inp=input(>>>) #去什麽東西裏面獲取什麽內容 v=getattr(obj,inp)
print(v)
#反射是通過字符串的形式操作對象相關的成員。一切事物都是對象!!! sho
=getattr(obj,show) print(sho)#<bound method Foo.show of <__main__.Foo object at 0x000001E00C46CA58>> sh=sho() print(sh)#alex-18 print(hasattr(obj,name))#True print(hasattr(obj,name1))#False setattr(obj,k1,v1) print(obj.k1) #v1 #obj.name print
(delattr(obj,name)) #NONE # obj.name

三種方式獲取obj對象中的name變量指向內存中的值 “gregory”

class Foo(object):
    def __init__(self):
        self.name = gregory

# 不允許使用 obj.name
obj = Foo()
print(obj.name)
print(obj.__dict__[name])
print(getattr(obj, name))

3.對象的嵌套

class F1:
    def __init__(self):
        self.name="greg"
class F2:
    def __init__(self,a): #a=f1=[name=greg]
        self.age=a
class F3:
    def __init__(self,b):#b=f2=[age=name=greg]
        self.dd=b

f1=F1()#[name=greg]
f2=F2(f1)#[age=name=greg]
f3=F3(f2)#[dd=[age=name=greg]]
# print(f3.dd) #<__main__.F2 object at 0x00000232ACA612B0>
# print(f3.dd.age) #18
print(f3.dd.age.name) #greg

4.異常(exception object)

4.1一些重要的內建異常

AttributeError 試圖訪問一個對象沒有的樹形,比如foo.x,但是foo沒有屬性x
IOError 輸入/輸出異常;基本上是無法打開文件
ImportError 無法引入模塊或包;基本上是路徑問題或名稱錯誤
IndentationError 語法錯誤(的子類) ;代碼沒有正確對齊
IndexError 下標索引超出序列邊界,比如當x只有三個元素,卻試圖訪問x[5]
KeyError 試圖訪問字典裏不存在的鍵
KeyboardInterrupt Ctrl+C被按下
NameError 使用一個還未被賦予對象的變量
SyntaxError Python代碼非法,代碼不能編譯(個人認為這是語法錯誤,寫錯了)
TypeError 傳入對象類型與要求的不符合
UnboundLocalError 試圖訪問一個還未被設置的局部變量,基本上是由於另有一個同名的全局變量,
導致你以為正在訪問它
ValueError 傳入一個調用者不期望的值,即使值的類型是正確的

4.2 捕捉異常
try:
    li=[11,22]
    li[999] #能捕獲錯誤
    # int(‘d3de‘)#不能捕獲錯誤
except IndexError as e:
    print(IndexError,e)
except ValueError as e:
    print(ValueError,e)
except Exception as e: #在python的異常中,有一個萬能異常:Exception,他可以捕獲任意異常
    print(Exception,e)
else:
    print(else)
finally: #finally語句不管try是否發生異常,都會被執行。
    print(……)

4.3 主動觸發異常

try:
    #主動觸發異常
    raise Exception(不過了……)
except Exception as e:
    print(e)

raise語句引發了一個沒有任何有關錯誤的普通異常。

4.4 捕捉異常寫到日誌

def db():
    # return True
    return False
def index():
    try:
        r=input(">>")
        int(r)
        result=db()
        if not result:
            raise Exception(數據庫處理錯誤)
    except Exception as e:
        str_error=str(e)
        print(str_error)
        #打開文件,寫錯誤記錄日誌
        r=open(log,a)
        r.write(str_error)
index()

4.5 自定義異常

class Gregerror(Exception):
    def __init__(self,msg):
        self.message=msg
    def __str__(self):
        return self.message

# obj=Gregerror(‘xxx‘)
# print(obj)

try:
    raise Gregerror("我錯了……")
except Gregerror as e:
    print(e) #e對象的__str__方法,獲取返回值

4.6 斷言

#assert條件
print(123)
assert 1==2#斷言
print(456)

4.7單例模式

單利模式存在的目的是保證當前內存中僅存在單個實例,避免內存浪費。

對於Python單例模式,創建對象時不能再直接使用:obj = Foo(),而應該調用特殊的方法:obj = Foo.get_instance() 。實例如下:

class Foo:
    __v=None

    @classmethod
    def get_instance(cls):
        if cls.__v:#如果它有值
            return cls.__v
        else:
            cls.__v=Foo()
            return cls.__v
#不要再使用 類()
obj=Foo.get_instance() #obj=創建的對象
print(obj)

obj2=Foo.get_instance()
print(obj2)

obj3=Foo.get_instance()
print(obj3)

# <__main__.Foo object at 0x000001B5A30E10F0>
# <__main__.Foo object at 0x000001B5A30E10F0>
# <__main__.Foo object at 0x000001B5A30E10F0>

Python 抽象篇:面向對象之高階