最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python面向?qū)ο竽Хǚ椒ê蛦卫K代碼實(shí)例

 更新時間:2020年03月25日 10:19:43   作者:jueyuanfengsheng  
這篇文章主要介紹了Python面向?qū)ο竽Хǚ椒ê蛦卫K代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

魔法方法

​ 凡是在類內(nèi)部定義,以“__開頭__結(jié)尾”的方法都稱之為魔法方法,又稱“類的內(nèi)置方法”, 這些方法會在某些條件成立時觸發(fā)。

經(jīng)常用到的雙下方法

  • __init__: 在調(diào)用類時觸發(fā)。
  • __delarttr__:
  • __getattr__: 會在對象.屬性時,“屬性沒有”的情況下才會觸發(fā)。對象.__dict__[屬性]不會觸發(fā)__getattr__,會報keyerror;
  • __getattribute__:會在對象.屬性時觸發(fā),不管有沒有該屬性都會觸發(fā);
  • __setattr__: 會在 “對象.屬性 = 屬性值” 時觸發(fā)。即:設(shè)置(添加/修改)屬性會觸發(fā)它的執(zhí)行;
  • __del__: 當(dāng)對象在內(nèi)存中被釋放時,自動觸發(fā)執(zhí)行,該方法會在最后執(zhí)行。
class Uderline_func:

  x = 100
  
  def __init__(self, y):
    print('類加括號調(diào)用的時候觸發(fā)我!')
    self.y = y # 當(dāng)與__setattr__方法同時存在時,self.y = y并不會被加載到對象的名稱空間
    # self['y'] = y # TypeError: 'Uderline_func' object does not support item assignment
  def general_func(self):
  
    print('隨便定義的一個函數(shù)!')


  # def __getattr__(self, item):
  #   print('只有對象獲取一個沒有的屬性值得時候觸發(fā)我!')
  
  def __getattribute__(self, item):
  
    print('類或?qū)ο鬅o論獲取的屬性有沒有都會觸發(fā)我!且出現(xiàn)我,對象點(diǎn)一個沒有的屬性會覆蓋掉__getattr__,還會導(dǎo)致__setattr__函數(shù)報錯')
  
  def __setattr__(self, key, value):
  
    print('設(shè)置屬性的時候觸發(fā)我!')
    # self.a = '在對象名稱空間增加一個值!' # 會一直觸發(fā)__setattr__,出現(xiàn)遞歸調(diào)用
    self.__dict__['a'] = '在對象名稱空間增加一個值!'
  def __delattr__(self, item):
  
    print('刪除值得時候觸發(fā)我!')
  
  def __del__(self):
  
    print('程序運(yùn)行完,被Python解釋器回收時,觸發(fā)我!')
# print(Uderline_func.__dict__) # 類在定義階段就已經(jīng)創(chuàng)建好了類名稱空間,將其內(nèi)部變量名和函數(shù)名塞進(jìn)去
u = Uderline_func(100) # 觸發(fā)__init__
# print(u.__dict__) # {'y': 100}
# Uderline_func.z # 只會觸發(fā)__getattribute__
u.z # 獲取沒有的屬性觸發(fā)__getattr__
# u.name = 'zhang' # 觸發(fā)__setattr__
# del u.x # 對象不能刪除掉類中的屬性,但只要執(zhí)行刪除操作,都會觸發(fā)__delattr__的執(zhí)行
  • __str__: 會在打印對象時觸發(fā)。
  • __call__: 會在對象被調(diào)用時觸發(fā)。
  • __new__: 會在__init__執(zhí)行前觸發(fā)。
class Uderline_func():
  x = 100
  # def __new__(cls, *args, **kwargs):
  #
  #   print('在__init__執(zhí)行之前觸發(fā)我,造一個空對象!')
  def __init__(self):
    print('類加括號調(diào)用的時候觸發(fā)我!')
  def __call__(self, *args, **kwargs):
    print('對象加括號調(diào)用的時候觸發(fā)我!')
  def __str__(self):
    print('對象被打印的時候觸發(fā)我!')
    return '必須要寫return返回一個字符串!不然報錯"TypeError: __str__ returned non-string (type NoneType)"'
u = Uderline_func()
u()
print(u)

__setitem__,__getitem,__delitem__

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

  def __getitem__(self, item):
    print(self.__dict__[item])

  def __setitem__(self, key, value):
    self.__dict__[key]=value

    # self.age = value # 也可以給對象添加屬性


  def __delitem__(self, key):
    print('del obj[key]時,我執(zhí)行')
    self.__dict__.pop(key)
  def __delattr__(self, item):
    print('del obj.key時,我執(zhí)行')
    self.__dict__.pop(item)
f1=Foo('sb')
f1['age']=18
# print(f1.__dict__)
f1['age1']=19
# del f1.age1
# del f1['age']
f1['name']='alex'
f1.xxx = 111
print(f1.__dict__) # {'name': 'alex', 'age': 18, 'age1': 19, 'xxx': 111}

1.__slots__是什么:是一個類變量,變量值可以是列表,元祖,或者可迭代對象,也可以是一個字符串(意味著所有實(shí)例只有一個數(shù)據(jù)屬性)

2.引子:使用點(diǎn)來訪問屬性本質(zhì)就是在訪問類或者對象的__dict__屬性字典(類的字典是共享的,而每個實(shí)例的是獨(dú)立的)

3.為何使用__slots__:字典會占用大量內(nèi)存,如果你有一個屬性很少的類,但是有很多實(shí)例,為了節(jié)省內(nèi)存可以使用__slots__取代

實(shí)例的__dict__

當(dāng)你定義__slots__后,__slots__就會為實(shí)例使用一種更加緊湊的內(nèi)部表示。實(shí)例通過一個很小的固定大小的數(shù)組來構(gòu)建,而不是為每個實(shí)例定義一個字典,這跟元組或列表很類似。在__slots__中列出的屬性名在內(nèi)部被映射到這個數(shù)組的指定小標(biāo)上。使用__slots__一個不好的地方就是我們不能再給實(shí)例添加新的屬性了,只能使用在__slots__中定義的那些屬性名。

4.注意事項:__slots__的很多特性都依賴于普通的基于字典的實(shí)現(xiàn)。另外,定義了__slots__后的類不再 支持一些普通類特性了,比如多繼承。大多數(shù)情況下,你應(yīng)該只在那些經(jīng)常被使用到 的用作數(shù)據(jù)結(jié)構(gòu)的類上定義__slots__比如在程序中需要創(chuàng)建某個類的幾百萬個實(shí)例對象 。

關(guān)于__slots__的一個常見誤區(qū)是它可以作為一個封裝工具來防止用戶給實(shí)例增加新的屬性。盡管使用__slots__可以達(dá)到這樣的目的,但是這個并不是它的初衷。 更多的是用來作為一個內(nèi)存優(yōu)化工具。

class Foo:
  __slots__ = 'x'
f1 = Foo()
f1.x = 1
f1.y = 2 # 報錯
print(f1.__slots__) # f1不再有__dict__屬性
print(f1.x) #依然能訪問
class Bar:
  __slots__ = ['x', 'y']
n = Bar()
n.x, n.y = 1, 2
n.z = 3 # 報錯

__doc__:查看類中注釋

class Foo:
  '我是描述信息'
  pass
print(Foo.__doc__)
class Foo:
  '我是描述信息'
  pass

class Bar(Foo):
  pass
print(Bar.__doc__) #該屬性無法繼承給子類

__module__和__class__

__module__:表示當(dāng)前操作的對象在那個模塊

 __class__:表示當(dāng)前操作的對象的類是什么

class C:
  def __init__(self):
    self.name = ‘SB'
from lib.aa import C
obj = C()
print obj.__module__ # 輸出 lib.aa,即:輸出模塊
print obj.__class__   # 輸出 lib.aa.C,即:輸出類

__enter__和__exit__

我們知道在操作文件對象的時候可以這么寫

with open('a.txt') as f:
  '代碼塊'

上述叫做上下文管理協(xié)議,即with語句,為了讓一個對象兼容with語句,必須在這個對象的類中聲明__enter__和__exit__方法

class Open:
  def __init__(self,name):
    self.name=name

  def __enter__(self):
    print('出現(xiàn)with語句,對象的__enter__被觸發(fā),有返回值則賦值給as聲明的變量')
    # return self
  def __exit__(self, exc_type, exc_val, exc_tb):
    print('with中代碼塊執(zhí)行完畢時執(zhí)行我啊')

with Open('a.txt') as f:
  print('=====>執(zhí)行代碼塊')
  # print(f,f.name)
  
'''
出現(xiàn)with語句,對象的__enter__被觸發(fā),有返回值則賦值給as聲明的變量
=====>執(zhí)行代碼塊
with中代碼塊執(zhí)行完畢時執(zhí)行我啊
'''

exit()中的三個參數(shù)分別代表異常類型,異常值和追溯信息,with語句中代碼塊出現(xiàn)異常,則with后的代碼都無法執(zhí)行

class Open:
  def __init__(self,name):
    self.name=name

  def __enter__(self):
    print('出現(xiàn)with語句,對象的__enter__被觸發(fā),有返回值則賦值給as聲明的變量')

  def __exit__(self, exc_type, exc_val, exc_tb):
    print('with中代碼塊執(zhí)行完畢時執(zhí)行我啊')
    print(exc_type)
    print(exc_val)
    print(exc_tb)


with Open('a.txt') as f:
  print('=====>執(zhí)行代碼塊')
  raise AttributeError('***著火啦,救火啊***')
print('0'*100) #------------------------------->不會執(zhí)行


'''
出現(xiàn)with語句,對象的__enter__被觸發(fā),有返回值則賦值給as聲明的變量
=====>執(zhí)行代碼塊
with中代碼塊執(zhí)行完畢時執(zhí)行我啊
<class 'AttributeError'>
***著火啦,救火啊***
<traceback object at 0x000000000A001E88>
Traceback (most recent call last):
 File "G:/Python代碼日常/第一階段/1階段/面向?qū)ο?test.py", line 52, in <module>
  raise AttributeError('***著火啦,救火啊***')
AttributeError: ***著火啦,救火啊***

'''

如果__exit()返回值為True,那么異常會被清空,就好像啥都沒發(fā)生一樣,with后的語句正常執(zhí)行

class Open:
  def __init__(self,name):
    self.name=name

  def __enter__(self):
    print('出現(xiàn)with語句,對象的__enter__被觸發(fā),有返回值則賦值給as聲明的變量')

  def __exit__(self, exc_type, exc_val, exc_tb):
    print('with中代碼塊執(zhí)行完畢時執(zhí)行我啊')
    print(exc_type)
    print(exc_val)
    print(exc_tb)
    return True
  with Open('a.txt') as f:
  print('=====>執(zhí)行代碼塊')
  raise AttributeError('***著火啦,救火啊***')
print('0'*100) #------------------------------->會執(zhí)行
class Open:
  def __init__(self,filepath,mode='r',encoding='utf-8'):
    self.filepath=filepath
    self.mode=mode
    self.encoding=encoding

  def __enter__(self):
    # print('enter')
    self.f=open(self.filepath,mode=self.mode,encoding=self.encoding)
    return self.f

  def __exit__(self, exc_type, exc_val, exc_tb):
    # print('exit')
    self.f.close()
    return True 
  def __getattr__(self, item):
    return getattr(self.f,item)

with Open('a.txt','w') as f:
  print(f)
  f.write('aaaaaa')
  f.wasdf #拋出異常,交給__exit__處理

用途或者說好處:

1.使用with語句的目的就是把代碼塊放入with中執(zhí)行,with結(jié)束后,自動完成清理工作,無須手動干預(yù)

2.在需要管理一些資源比如文件,網(wǎng)絡(luò)連接和鎖的編程環(huán)境中,可以在__exit__中定制自動釋放資源的機(jī)制,你無須再去關(guān)系這個問題,這將大有用處

單例模式

單例模式:多次實(shí)例化的結(jié)果指向同一個實(shí)例

方式1

# @classmethod(用類綁定方法)

import settings

class MySQL:
  __instance=None
  def __init__(self, ip, port):
    self.ip = ip
    self.port = port
  @classmethod
  def from_conf(cls):
    if cls.__instance is None:
      cls.__instance=cls(settings.IP, settings.PORT)
    return cls.__instance
obj1=MySQL.from_conf()
obj2=MySQL.from_conf()
obj3=MySQL.from_conf()
# obj4=MySQL('1.1.1.3',3302)
print(obj1)
print(obj2)
print(obj3)
# print(obj4)

方式2

# 用類裝飾器
import settings

def singleton(cls):
 _instance=cls(settings.IP,settings.PORT)
 def wrapper(*args,**kwargs):
   if len(args) !=0 or len(kwargs) !=0:
     obj=cls(*args,**kwargs)
     return obj
   return _instance
 return wrapper

@singleton #MySQL=singleton(MySQL) #MySQL=wrapper
class MySQL:
 def __init__(self, ip, port):
   self.ip = ip
   self.port = port

# obj=MySQL('1.1.1.1',3306) #obj=wrapper('1.1.1.1',3306)
# print(obj.__dict__)

obj1=MySQL() #wrapper()
obj2=MySQL() #wrapper()
obj3=MySQL() #wrapper()
obj4=MySQL('1.1.1.3',3302) #wrapper('1.1.1.3',3302)
print(obj1)
print(obj2)
print(obj3)
print(obj4)

方式3

# 調(diào)用元類
import settings

class Mymeta(type):
  def __init__(self,class_name,class_bases,class_dic):
    #self=MySQL這個類
    self.__instance=self(settings.IP,settings.PORT)

  def __call__(self, *args, **kwargs):
    # self=MySQL這個類
    if len(args) != 0 or len(kwargs) != 0:
      obj=self.__new__(self)
      self.__init__(obj,*args, **kwargs)
      return obj
    else:
      return self.__instance

class MySQL(metaclass=Mymeta): #MySQL=Mymeta(...)
  def __init__(self, ip, port):
    self.ip = ip
    self.port = port
obj1=MySQL()
obj2=MySQL()
obj3=MySQL()
obj4=MySQL('1.1.1.3',3302)
print(obj1)
print(obj2)
print(obj3)
print(obj4)

方式4

# 利用模塊多次導(dǎo)入只產(chǎn)生一次名稱空間,多次導(dǎo)入只沿用第一次導(dǎo)入成果。
def f1():
  from singleton import instance
  print(instance)

def f2():
  from singleton import instance,My
  SQL
  print(instance)
  obj=MySQL('1.1.1.3',3302)
  print(obj)

f1()
f2()

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 修改默認(rèn)的pip版本為對應(yīng)python2.7的方法

    修改默認(rèn)的pip版本為對應(yīng)python2.7的方法

    今天小編就為大家分享一篇修改默認(rèn)的pip版本為對應(yīng)python2.7的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-11-11
  • Python?Selenium如何切換瀏覽器的頁面

    Python?Selenium如何切換瀏覽器的頁面

    這篇文章主要介紹了Python?Selenium如何切換瀏覽器的頁面的相關(guān)資料,在使用Selenium進(jìn)行網(wǎng)頁測試時,跳轉(zhuǎn)頁面后常會出現(xiàn)無法定位元素的問題,解決這一問題的關(guān)鍵是學(xué)會在多個瀏覽器標(biāo)簽頁或窗口間切換,需要的朋友可以參考下
    2024-10-10
  • 一文實(shí)現(xiàn)刪除numpy數(shù)組中的指定索引元素

    一文實(shí)現(xiàn)刪除numpy數(shù)組中的指定索引元素

    在Python中,Numpy是一個強(qiáng)大的數(shù)學(xué)庫,用于處理大型多維數(shù)組和矩陣的數(shù)學(xué)運(yùn)算,數(shù)組是由相同類型的數(shù)據(jù)元素組成的集合,并且每個元素都可以通過索引進(jìn)行訪問,本文將給大家介紹如何刪除numpy數(shù)組中的指定索引元素,需要的朋友可以參考下
    2024-05-05
  • 50行Python代碼實(shí)現(xiàn)人臉檢測功能

    50行Python代碼實(shí)現(xiàn)人臉檢測功能

    現(xiàn)在的人臉識別技術(shù)已經(jīng)得到了非常廣泛的應(yīng)用,支付領(lǐng)域、身份驗(yàn)證、美顏相機(jī)里都有它的應(yīng)用。下面小編給大家?guī)砹嘶?0行Python代碼實(shí)現(xiàn)人臉檢測功能,一起看看吧
    2018-01-01
  • pytorch 中forward 的用法與解釋說明

    pytorch 中forward 的用法與解釋說明

    這篇文章主要介紹了pytorch 中forward 的用法與解釋說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • tornado+celery的簡單使用詳解

    tornado+celery的簡單使用詳解

    今天小編就為大家分享一篇tornado+celery的簡單使用詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • Python 利用pandas和mysql-connector獲取Excel數(shù)據(jù)寫入到MySQL數(shù)據(jù)庫

    Python 利用pandas和mysql-connector獲取Excel數(shù)據(jù)寫入到MySQL數(shù)據(jù)庫

    在實(shí)際應(yīng)用中,我們可能需要將Excel表格中的數(shù)據(jù)導(dǎo)入到MySQL數(shù)據(jù)庫中,以便于進(jìn)行進(jìn)一步的數(shù)據(jù)分析和處理,本文將介紹如何使用Python將Excel表格中的數(shù)據(jù)插入到MySQL數(shù)據(jù)庫中,需要的朋友可以參考下
    2023-10-10
  • Python?numpy中np.random.seed()的詳細(xì)用法實(shí)例

    Python?numpy中np.random.seed()的詳細(xì)用法實(shí)例

    在學(xué)習(xí)人工智能時,大量的使用了np.random.seed(),利用隨機(jī)數(shù)種子,使得每次生成的隨機(jī)數(shù)相同,下面這篇文章主要給大家介紹了關(guān)于Python?numpy中np.random.seed()的詳細(xì)用法,需要的朋友可以參考下
    2022-08-08
  • Python操作Mysql實(shí)例代碼教程在線版(查詢手冊)

    Python操作Mysql實(shí)例代碼教程在線版(查詢手冊)

    本文介紹了Python操作MYSQL、執(zhí)行SQL語句、獲取結(jié)果集、遍歷結(jié)果集、取得某個字段、獲取表字段名、將圖片插入數(shù)據(jù)庫、執(zhí)行事務(wù)等各種代碼實(shí)例和詳細(xì)介紹,代碼居多,是一桌豐盛唯美的代碼大餐
    2013-02-02
  • Django實(shí)現(xiàn)簡單登錄的示例代碼

    Django實(shí)現(xiàn)簡單登錄的示例代碼

    本文主要介紹了Django實(shí)現(xiàn)簡單登錄的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11

最新評論

包头市| 青浦区| 汶川县| 蓬溪县| 南阳市| 珲春市| 岢岚县| 上饶县| 上思县| 景泰县| 二手房| 福海县| 剑阁县| 分宜县| 山阴县| 合作市| 阿勒泰市| 色达县| 阳江市| 乐陵市| 基隆市| 拜泉县| 宝坻区| 营山县| 突泉县| 新营市| 广州市| 大竹县| 尚志市| 普安县| 襄樊市| 波密县| 成都市| 晋州市| 高唐县| 喀什市| 万山特区| 武义县| 江孜县| 崇义县| 同心县|