欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Python 私有屬性和名字重整、魔法屬性和方法、上下文管理器

系統 1923 0

修改、查看私有屬性、名字重整

如下,Test類定義 一個私有屬性 __name? 實例化一個對象 a ,無法調用該屬性,

打印 a.__dict__( 可以檢查一個對象的所有屬性 )查看?,發現__name存在并且名字變為? _Test__name (無法調用的原因,名字被改變)

改變規則:私有屬性前添加類名,再在類名前添加一個下劃線 ( 名字重整

Python 私有屬性和名字重整、魔法屬性和方法、上下文管理器_第1張圖片

我們驗證一下,打印修改后的屬性,如下

?

這里有個疑問,既然無法直接打印,那我們為什么可以直接修改?

修改測試一下,打印輸出,此時__name 并不是私有屬性了,此時的 __name 只是添加了一個屬性,可以直接調用

這里就沒有什么私有公有之說了,所謂的公有私有,是指類中的屬性,實例對象無法直接調用

Python 私有屬性和名字重整、魔法屬性和方法、上下文管理器_第2張圖片 ? ? ? ? ? ? ?

另外補充一下 __dict__屬性,Test類也是一個對象,查看其屬性:每個魔法屬性對應值或函數

?

?

魔法屬性、方法

無論人或事物往往都有不按套路出牌的情況,Python的類屬性也是如此。存在一些具有特殊含義的屬性

如上圖,對應的魔法屬性:

?

1. __doc__ :表示類的描述信息,help()方法也可以輸出類的描述信息

            
              class Test():
    """
    This is a description of a class
    """
    pass


print(Test.__doc__)
print("*" * 15)
print(help(Test))
            
          

Python 私有屬性和名字重整、魔法屬性和方法、上下文管理器_第3張圖片

?

2. __module__? 和 __class__ :__module__表示當前操作在哪個模塊,__class__表示當前操作的對象的類是什么

            
              # -*- coding:utf-8 -*-


# test.py
class Person(object):
    def __init__(self):
        self.name = 'laowang'
            
          
            
              

from test import Person


# main.py
obj = Person()
print(obj.__module__)  # 輸出創建該對象的對應模塊  test
print(obj.__class__)  # 輸出創建該對象的對應模塊中的類    test.Person
            
          

?

3. __init__ :初始化方法(不建議稱其為構造方法,可以說__init__ 和 __new__ 方法一起完成了構造方法的功能),通過類創建對象時,自動觸發執行

            
              class Person:
    def __init__(self, name):
        self.name = name
        self.age = 18


obj = Person('laowang')  # 自動執行類中的 __init__ 方法

            
          

?

4. __del__:當對象在內存中被釋放時,自動觸發執行

注:此方法無需定義,因為python是一門高級語言,程序員在使用時,無需關系內存的分配和釋放,因為此工作都是交給Python的解釋器來執行,所以,__del__的調用是有解釋器在進行垃圾回收時自動觸發執行的。

            
              class Foo:
    def __del__(self):
        pass
            
          

?

5. __call__:對象后面加括號,觸發執行? (用于裝飾器)

注:__init__方法的執行是由創建對象觸發的,即 對象 = 類名() ; 而對于__call__ 方法執行是由對象后加括號觸發的,即

對象()? 類()

            
              class Foo:
    def __init__(self):
        pass

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


obj = Foo()  # 執行 __init__
obj()  # 執行 __call__
            
          

?

6. __dict__ :?類或對象中的所有屬性? ? ? ? ?

類的實例屬性屬于對象;類中的類屬性和方法等屬于類,即:

            
              class Province(object):
    country = 'China'

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

    def func(self, *args, **kwargs):
        print('func')

# 獲取類的屬性,即:類屬性、方法、
print(Province.__dict__)
# 輸出:{'__dict__': 
              
                , '__module__': '__main__', 'country': 'China', '__doc__': None, '__weakref__': 
                
                  , 'func': 
                  
                    , '__init__': 
                    
                      }

obj1 = Province('山東', 10000)
print(obj1.__dict__)
# 獲取 對象obj1 的屬性
# 輸出:{'count': 10000, 'name': '山東'}

obj2 = Province('山西', 20000)
print(obj2.__dict__)
# 獲取 對象obj1 的屬性
# 輸出:{'count': 20000, 'name': '山西'}
                    
                  
                
              
            
          

?

7.?__str__:如果一個類中定義了__str__方法,那么在打印 對象 時,默認輸出該方法的返回值

            
              class Foo:
    def __str__(self):
        return 'laowang'


obj = Foo()
print(obj)
# 輸出:laowang
            
          

?

8.?__getitem__、__setitem__、__delitem__ :用于索引操作,如字典。以上分別表示獲取、設置、刪除數據

            
              # -*- coding:utf-8 -*-

class Foo(object):

    def __getitem__(self, key):
        print('__getitem__', key)

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

    def __delitem__(self, key):
        print('__delitem__', key)


obj = Foo()

result = obj['k1']      # 自動觸發執行 __getitem__
obj['k2'] = 'laowang'   # 自動觸發執行 __setitem__
del obj['k1']           # 自動觸發執行 __delitem__
            
          

9.?__getitem__、__setitem__、__delitem__ :該三個方法用于分片操作,如:列表

            
              # -*- coding:utf-8 -*-

class Foo(object):

    def __getslice__(self, i, j):
        print('__getslice__', i, j)

    def __setslice__(self, i, j, sequence):
        print('__setslice__', i, j)

    def __delslice__(self, i, j):
        print('__delslice__', i, j)

obj = Foo()

obj[-1:1]                   # 自動觸發執行 __getslice__
obj[0:1] = [11,22,33,44]    # 自動觸發執行 __setslice__
del obj[0:2]                # 自動觸發執行 __delslice__
            
          

?

?

With、上下文管理器

對于系統資源如文件、數據庫連接、socket 而言,應用程序打開這些資源并執行完業務邏輯之后,必須做的一件事就是要關閉(斷開)該資源。

比如 Python 程序打開一個文件,往文件中寫內容,寫完之后,就要關閉該文件,否則會出現什么情況呢?極端情況下會出現 "Too many open files" 的錯誤,因為系統允許你打開的最大文件數量是有限的。

同樣,對于數據庫,如果連接數過多而沒有及時關閉的話,就可能會出現 "Can not connect to MySQL server Too many connections",因為數據庫連接是一種非常昂貴的資源,不可能無限制的被創建。

普通版:

            
              def m1():
    f = open("output.txt", "w")
    f.write("python之禪")
    f.close()
            
          

這樣寫有一個潛在的問題,如果在調用 write 的過程中,出現了異常進而導致后續代碼無法繼續執行,close 方法無法被正常調用,因此資源就會一直被該程序占用者釋放。

?

進階版:

            
              def m2():
    f = open("output.txt", "w")
    try:                      
        f.write("python之禪")
    except IOError:            # except 未捕獲到對應異常,依然會崩
        print("oops error")
    finally:
        f.close()
            
          

改良版本的程序是對可能發生異常的代碼處進行 try 捕獲,使用 try/finally 語句,該語句表示如果在 try 代碼塊中程序出現了異常,后續代碼就不再執行,而直接跳轉到 except 代碼塊。而無論如何,finally 塊的代碼最終都會被執行。因此,只要把 close 放在 finally 代碼中,文件就一定會關閉。

?

高級版:

            
              def m3():
    with open("output.txt", "r") as f:
        f.write("Python之禪")
            
          

一種更加簡潔、優雅的方式就是用 with 關鍵字。 open 方法的返回值賦值給變量 f,當離開 with 代碼塊的時候,系統會自動調用 f.close() 方法, with 的作用和使用 try/finally 語句是一樣的。那么它的實現原理是什么?在講 with 的原理前要涉及到另外一個概念,就是 上下文管理器(Context Manager)

?

上下文(context)

上下文在不同的地方表示不同的含義,要感性理解。context其實說白了,和文章的上下文是一個意思,通俗一點,理解為環境

?

上下文管理器

任何實現了 __enter__() 和 __exit__() 方法的對象都可稱之為上下文管理器 ,上下文管理器對象可以使用 with 關鍵字。顯然,文件(file)對象也實現了上下文管理器。

那么文件對象是如何實現這兩個方法的呢?我們可以模擬實現一個自己的文件類,讓該類實現 __enter__() __exit__() 方法。

            
              class File():

    def __init__(self, filename, mode):
        self.filename = filename
        self.mode = mode

    def __enter__(self):
        print("entering")
        self.f = open(self.filename, self.mode)
        return self.f

    def __exit__(self, *args):
        print("will exit")
        self.f.close()
            
          

__enter__() 方法返回資源對象,這里就是你將要打開的那個文件對象,__exit__() 方法處理一些清除工作。

因為 File 類實現了上下文管理器,現在就可以使用 with 語句了。

            
              with File('out.txt', 'w') as f: 
# 實例化File對象,執行__init__方法,filename屬性對應out.txt,w對應mode屬性
# with判斷其是否是一個上下文管理器(實現對應的方法),然后自動調用 __enter__()方法 
# __enter__()方法返回值是什么,對應的 f 就是什么,而當結束或者出現異常時,會自動調用 __exit__()
# 方法
    print("writing")
    f.write('hello, python')
            
          

這樣,你就無需顯示地調用 close 方法了,由系統自動去調用,哪怕中間遇到異常 close 方法也會被調用。

?

實現上下文管理器的另外方式(了解)

Python 還提供了一個 contextmanager 的裝飾器,更進一步簡化了上下文管理器的實現方式。通過 yield 將函數分割成兩部分,yield 之前的語句在 __enter__ 方法中執行,yield 之后的語句在 __exit__ 方法中執行。緊跟在 yield 后面的值是函數的返回值。

            
              from contextlib import contextmanager

@contextmanager
def my_open(path, mode):
    f = open(path, mode)
    yield f
    f.close()
調用

with my_open('out.txt', 'w') as f:
    f.write("hello , the simplest context manager")
            
          

?

?

總結

Python 提供了? with 語法用于簡化資源操作的后續清除操作,是 try/finally 的替代方法,實現原理建立在上下文管理器之上。 此外,Python 還提供了一個 contextmanager 裝飾器,更進一步簡化上下管理器的實現方式。

?

?

?

?


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 精品国产第一国产综合精品gif | 精品一卡2卡三卡四卡二卡 欧美不卡一区二区三区在线观看 | 成人在线观看国产 | 亚洲日本va在线视频观看 | 青青青青娱乐 | A片人人澡C片人人大片 | 日韩精品在线一区 | 国产美女高清片免费观看 | 美女午夜色视频在线观看 | 日本污污视频在线观看 | 日韩专区中文字幕 | 亚洲播播播 | 成人黄色在线观看 | 日产国产精品久久久久久 | 久久一区二区三区四区 | 波多野结衣的一级片 | 中国大陆高清aⅴ毛片 | 亚洲精品欧美综合四区 | 亚洲精品1区 | 欧美在线一区二区三区 | 亚洲永久 | 亚洲精品成人 | 国产孰妇精品AV片国产m3u8 | 奇米色偷偷 | 欧美久操| 久草福利资源网站免费 | 亚州一区二区三区 | 清纯唯美综合 | 日本高清在线中文字幕网 | www.尤物视频.com | 久久中文字幕一区二区三区 | 在线不卡一区 | 亚洲日本久久久午夜精品 | 欧美www在线观看 | 国产福利一区二区在线精品 | 久久99国产精品 | www香蕉视频 | 成年人国产网站 | 香港三级午夜理伦三级 | 在线播放国产一区二区三区 | 激情五月激情综合网 |