py-opp 类(class)
生活随笔
收集整理的這篇文章主要介紹了
py-opp 类(class)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?類的創建
class 類名:passclass 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 = nameself.a = ageself.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 = nself.age = aself.xue = 'o'b1 = Bar('alex', 123)b2 = Bar('eric', 456) View Code1.1適用場景
#給對象封裝一些值 如果多個函數中有一些相同參數時,轉換成面向對象
class DataBaseHelper:def __init__(self, ip, port, username, pwd):self.ip = ipself.port = portself.username = usernameself.pwd = pwddef 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 Code2.繼承
1、繼承class 父類:passclass 子類(父類):pass2、重寫防止執行父類中的方法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):# objprint('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):passobj = 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__ = MyTypedef __init__(self, name):self.name = namedef __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 = 1print(i)---異常的捕捉---def fun():ret = 0try: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 = 1print('沒有錯誤。。')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 Truereturn Falsedef 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 = msgdef __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
反射
通過字符串的形式操作對象相關的屬性。python中的一切事物都是對象(都可以使用反射)
class Foo:def __init__(self, name,age):self.name = nameself.age = agedef show(self):return "%s-%s " %(self.name,self.age)def __int__(self):return 123def __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 = nameself.age = ageobj = Foo() # obj是Foo的對象,obj也可以叫做Foo類的 實例(實例化) obj1 = Foo() obj2 = Foo() obj3 = Foo() 平時我們創建對象,都是 對象名=類() 這里每個obj對象都是獨立的內存地址,然而在某些運用環境下需要使用同一個對象 能不能創建一個實例后,接下來的實例都用同一份實例(或對象),當然可以啦,就是下面的單例模式class Foo:def __init__(self, name,age):self.name = nameself.age = agedef show(self):print(self.name,self.age)v = Nonewhile True:if v:v.show()else:v = Foo('alex', 123)v.show() 剛開始v是None,進入while 循環會創建一個實例,后面調用v實例就不用創建了,直接調用他的方法高級一點的表現 class Foo:__v = None@classmethoddef get_instance(cls):if cls.__v:return cls.__velse: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實際運用
當用戶操作數據庫操作數據庫連接池時,連接池的接口數量是一定的,用戶連接只能共用創建好的連接,不能再創建,當連接都被占用,只有等釋放后,供下一個用戶連接
總結
以上是生活随笔為你收集整理的py-opp 类(class)的全部內容,希望文章能夠幫你解決所遇到的問題。