1. 程式人生 > >week6:面向物件之成員修飾符,特殊成員,異常處理,發射,單例

week6:面向物件之成員修飾符,特殊成員,異常處理,發射,單例

一、成員修飾符

共有成員
私有成員, __欄位名
 - 無法直接訪問,只能間接訪問
        

class Foo:

    def __init__(self, name, age):
        self.name = name
        # self.age = age
        self.__age = age # 私有,外部無法直接訪問

    def show(self):
        return self.__age


obj = Foo('alex', 19)
print(obj.name)
# print(obj.age)
# print(obj.__age)
ret = obj.show()
print(ret)
class Foo:
    __v = '123'

    def __init__(self):
        pass
    def show(self):
        return Foo.__v
    @staticmethod
    def stat():
        return Foo.__v
# print(Foo.__v)
# ret = Foo().show()  ##foo()是建立物件的意思
# print(ret)

ret = Foo.stat()
print(ret)
class Foo:
    def __f1(self):
        return 123

    def f2(self):
        r = self.__f1()
        return r

obj = Foo()
ret = obj.f2()
print(ret)  ##123
class F:
    def __init__(self):
        self.ge = 123
        self.__gene = 123

class S(F):
    def __init__(self, name):
        self.name = name
        self.__age = 18
        super(S, self).__init__()

    def show(self):
        print(self.name)##alex
        print(self.__age)##18
        # print(self.ge)
        # print(self.__gene)

s = S('alex')
s.show()

 二、特殊成員

    __init__     類()   自動執行
    __del__
    __call__     物件()  類()()    自動執行

class Foo:
    def __init__(self):
        print('init')

    def __call__(self, *args, **kwargs):
        print('call')

# obj = Foo()
# obj()
Foo()()

    __int__      int(物件) 

  __str__      str()

# s = "123"
# # s = str('123')
#
# i = int(s)
# print(i,type(i))
class Foo:

    def __init__(self):
        pass

    def __int__(self):
        return 1111

    def __str__(self):
        return 'alex'

obj = Foo()
print(obj, type(obj))

# int,物件,自動執行物件的 __int__方法,並將返回值賦值給int物件
r = int(obj)
print(r)
i = str(obj)
print(i)
class Foo:

    def __init__(self,n,a):
        self.name =n
        self.age =a

    def __str__(self):
        return '%s-%s' % (self.name, self.age,)

obj = Foo('alex', 18)
print(obj) #print(str(obj)) str(obj)   obj中__str__,並獲取其返回值

    __add__

class Foo:

    def __init__(self, name,age):
        self.name = name
        self.age = age

    def __add__(self, other):
        # self = obj1 (alex,19)
        # other = obj2(eric,66)
        # return self.age + other.age
        #return Foo('tt',99)
        return Foo(obj1.name, other.age)

    def __del__(self):
        print('析構方法') # 物件被銷燬()時,自動執行

obj1 = Foo('alex', 19)
obj2 = Foo('eirc', 66)

r = obj1 + obj2
# 兩個物件相加時,自動執行第一個物件的的 __add__方法,並且將第二個物件當作引數傳遞進入
print(r,type(r))


    __dict__     # 講物件中封裝的所有內容通過字典的形式返回

class Foo:
    def __init__(self, name,age):
        self.name = name
        self.age = age
        self.n = 123

# obj = Foo('alex', 18)
#
# d = obj.__dict__
# print(d)

# ret = Foo.__dict__
# print(ret)

    __getitem__  # 切片(slice型別)或者索引
    __setitem__
    __delitem__

class Foo:

    def __init__(self, name,age):
        self.name = name
        self.age = age

    def __getitem__(self, item):
        return item+10

    def __setitem__(self, key, value):
        print(key,value)

    def __delitem__(self, key):
        print(key)
li = Foo('alex', 18)
r= li[8] # 自動執行li物件的類中的 __getitem__方法,8當作引數傳遞給item
print(r)

li[100] = "asdf"

del li[999]


    __iter__
               

class Foo:

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __iter__(self):
        return iter([11, 22, 33])
li = Foo('alex', 18)
# 如果類中有 __iter__ 方法,物件=》可迭代物件
# 物件.__iter__() 的返回值: 迭代器
# for 迴圈,迭代器,next
# for 迴圈,可迭代物件,物件.__iter__(),迭代器,next
# 1、執行li物件的類中的 __iter__方法,並獲取其返回值
# 2、迴圈上一步中返回的物件
for i in li:
    print(i)

三、metaclass,類的祖宗  

a. Python中一切事物都是物件
b. 
        class Foo:
            pass
              
        obj = Foo()
        # obj是物件,Foo類
        # Foo類也是一個物件,type的物件

 c. 
        類都是type類的物件   type(..)
        “物件”都是類的物件 類()

class MyType(type):
    def __init__(self, *args, **kwargs):
        # self=Foo
        print(123)
        pass

    def __call__(self, *args, **kwargs):
        # self=Foo
        r = self.__new__(self, *args, **kwargs)
        print(r)



class Foo(object,metaclass=MyType):
    def __init__(self):
        pass

    def __new__(cls, *args, **kwargs):
        return '物件'

    def func(self):
        print('hello wupeiqi')

obj = Foo()

四、異常處理   

raise Exception('資料庫處理錯誤')

while True:
     try:
         # 程式碼塊,邏輯
         inp = input('請輸入序號:')
         i = int(inp)
     except Exception as e:
         # e是Exception物件,物件中封裝了錯誤資訊
         # 上述程式碼塊如果出錯,自動執行當前塊的內容
         print(e)
         i = 1
     print(i)

 li = [11,22]
 li[999] # IndexError
 int('qwe') # ValueError
try:
        li = [11, 22]
        li[10]
        # int('w3r')
except IndexError as e:
        print('IndexError', e)

IndexError list index out of range

但是

try:
        li = [11, 22]
        #li[10]
        int('w3r')
except IndexError as e:
        print('IndexError', e)    報錯
def fun():
    ret = 0
    try:
        li = [11, 22]
        li[1]
        #int('w3r')

    except IndexError as e:
        print('IndexError',e)
    except ValueError as e:
        print('ValueError',e)
    except Exception as e:
        print('Exception',e)
    else:
        ret = 1
        print('elese')
    finally:
        print('....')

    return ret
r = fun()
if r == 0:
    print('500')
else:
    pass
try:
    # int('asdf')
    # 主動觸發異常
    # raise Exception('不過了...')
except Exception as e:
    print(e)


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()
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__()方法,獲取返回

# assert 條件,斷言,用於強制使用者服從,不服從就報錯,可捕獲,一般不捕獲
# print(23)
# assert 1==2
# print(456)

五、反射

"""
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)
b = 'name'
"""


# getattr   獲取屬性
# hasattr
# setattr
# delattr

# 通過字串的形式操作物件中的成員

# func = getattr(obj, 'show')
# print(func)
# r = func()
# print(r)

# print(hasattr(obj, 'name'))
# obj.k1
# setattr(obj, 'k1', 'v1')
# print(obj.k1)
# obj.name
# delattr(obj, 'name')
# obj.name

# 去什麼東西里面獲取什麼內容
# inp = input('>>>')
# v = getattr(obj, inp)
# print(v)

"""
obj.name
b = "name"
obj.b # obj.name 兩者沒有任何關係
"""
# b = "name"
# obj.__dict__['name']
# obj.__dict__[b]

# if b == 'name':
#     obj.name
"""
class Foo:

    stat = '123'

    def __init__(self, name,age):
        self.name = name
        self.age = age

# 通過字串的形式操作物件中的成員
r = getattr(Foo, 'stat')
print(r)
"""
"""
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.py

# NAME = 'alex'
#
# def func():
#     return 'qwe'
#
# class Foo:
#     def __init__(self):
#         self.name = 123


def f1():
    return '首頁'

def f2():
    return '新聞'

def f3():
    return '精華'

六、單例模式

# 單例,用於使用同一份例項(物件)
"""
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()
"""
class Foo:

    __v = None

    @classmethod
    def get_instance(cls):
        if cls.__v:
            return cls.__v
        else:
            cls.__v = Foo()
            return cls.__v

# 不要在使用 類()
obj1 = Foo.get_instance()
print(obj1)
obj2 = Foo.get_instance()
print(obj2)
obj3 = Foo.get_instance()
print(obj3)