python any,call,init,下劃線知識匯總

  • 2020 年 11 月 22 日
  • 筆記

python補充

any()

【來自菜鳥教程】
any() 函數用於判斷給定的可迭代參數 iterable 是否全部為 False,則返回 False,如果有一個為 True,則返回 True。

元素除了是 0、空、FALSE 外都算 TRUE。

函數等價於:

def any(iterable):
    for element in iterable:
        if element:
            return True
    return False

>>>any(['a', 'b', 'c', 'd'])  # 列表list,元素都不為空或0
True
 
>>> any(['a', 'b', '', 'd'])   # 列表list,存在一個為空的元素
True
 
>>> any([0, '', False])        # 列表list,元素全為0,'',false
False
 
>>> any(('a', 'b', 'c', 'd'))  # 元組tuple,元素都不為空或0
True
 
>>> any(('a', 'b', '', 'd'))   # 元組tuple,存在一個為空的元素
True
 
>>> any((0, '', False))        # 元組tuple,元素全為0,'',false
False
  
>>> any([]) # 空列表
False
 
>>> any(()) # 空元組
False

call和init方法

//www.cnblogs.com/yinyoupoet/p/13287359.html

python類中,__init____call__方法都是用來初始化類的,但是它們之間存在一些區別。

__init__是用來在初始化類的對象時被調用,同時可以傳入一些參數。
__call__用來在調用該對象時被觸發。
具體可以看下面的例子

class A:
    def __init__(self):
        print "init"
    
    def __call__(self):
        print "call"

a = A() # 輸出 init
a() # 輸出 call

下劃線的含義

Python中下劃線的5種含義 – 地球的外星人君的文章 – 知乎 //zhuanlan.zhihu.com/p/36173202

  • 單前導下劃線:_var

  • 單末尾下劃線:var_

  • 雙前導下劃線:__var

  • 雙前導和末尾下劃線:var

  • 單下劃線:_

單前導下劃線 _var

當涉及到變數和方法名稱時,單個下劃線前綴有一個約定俗成的含義。 它是對程式設計師的一個提示 – 意味著Python社區一致認為它應該是什麼意思,但程式的行為不受影響。

下劃線前綴的含義是告知其他程式設計師:以單個下劃線開頭的變數或方法僅供內部使用。

這不是Python強制規定的。 Python不像Java那樣在「私有」和「公共」變數之間有很強的區別。 這就像有人提出了一個小小的下劃線警告標誌,說:

「嘿,這不是真的要成為類的公共介面的一部分。不去管它就好。「

單個下劃線是一個Python命名約定,表示這個名稱是供內部使用的。 它通常不由Python解釋器強制執行,僅僅作為一種對程式設計師的提示。

單末尾下劃線:var_

解決和關鍵字的命名衝突

有時候,一個變數的最合適的名稱已經被一個關鍵字所佔用。 因此,像class或def這樣的名稱不能用作Python中的變數名稱。 在這種情況下,你可以附加一個下劃線來解決命名衝突:

>>> def make_object(name, class):
SyntaxError: "invalid syntax"

>>> def make_object(name, class_):
...    pass

總之,單個末尾下劃線(後綴)是一個約定,用來避免與Python關鍵字產生命名衝突。 PEP 8解釋了這個約定。

雙前導下劃線:__var

雙下劃線前綴會導致Python解釋器重寫屬性名稱,以避免子類中的命名衝突。

名稱修飾:- 解釋器更改變數的名稱,以便在類被擴展的時候不容易產生衝突。

class Test:
   def __init__(self):
       self.foo = 11
       self._bar = 23
       self.__baz = 23

讓我們用內置的dir()函數來看看這個對象的屬性:

>>> t = Test()
>>> dir(t)
['_Test__baz', '__class__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'__weakref__', '_bar', 'foo']

注意__baz變成了 _Test__baz

作者:地球的外星人君
鏈接://zhuanlan.zhihu.com/p/36173202
來源:知乎
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

讓我們創建另一個擴展Test類的類,並嘗試重寫構造函數中添加的現有屬性:

class ExtendedTest(Test):
   def __init__(self):
       super().__init__()
       self.foo = 'overridden'
       self._bar = 'overridden'
       self.__baz = 'overridden'

現在,你認為foo,_bar和__baz的值會出現在這個ExtendedTest類的實例上嗎? 我們來看一看:

>>> t2 = ExtendedTest()
>>> t2.foo
'overridden'
>>> t2._bar
'overridden'
>>> t2.__baz
AttributeError: "'ExtendedTest' object has no attribute '__baz'"

等一下,當我們嘗試查看t2 .__ baz的值時,為什麼我們會得到AttributeError? 名稱修飾被再次觸發了! 事實證明,這個對象甚至沒有__baz屬性:

>>> dir(t2)
['_ExtendedTest__baz', '_Test__baz', '__class__', '__delattr__',
'__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__gt__', '__hash__', '__init__', '__le__',
'__lt__', '__module__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', '__weakref__', '_bar', 'foo', 'get_vars']

正如你可以看到__baz變成_ExtendedTest__baz以防止意外修改:

>>> t2._ExtendedTest__baz
'overridden'

但原來的_Test__baz還在:

>>> t2._Test__baz
42

雙下劃線名稱修飾對程式設計師是完全透明的。 下面的例子證實了這一點:

class ManglingTest:
   def __init__(self):
       self.__mangled = 'hello'

   def get_mangled(self):
       return self.__mangled

>>> ManglingTest().get_mangled()
'hello'
>>> ManglingTest().__mangled
AttributeError: "'ManglingTest' object has no attribute '__mangled'"

名稱修飾是否也適用於方法名稱? 是的,也適用。名稱修飾會影響在一個類的上下文中,以兩個下劃線字元(”dunders”)開頭的所有名稱:

class MangledMethod:
   def __method(self):
       return 42

   def call_it(self):
       return self.__method()

>>> MangledMethod().__method()
AttributeError: "'MangledMethod' object has no attribute '__method'"
>>> MangledMethod().call_it()
42

這是另一個也許令人驚訝的運用名稱修飾的例子:

_MangledGlobal__mangled = 23

class MangledGlobal:
   def test(self):
       return __mangled

>>> MangledGlobal().test()
23
雙前導和末尾下劃線:__var__

也許令人驚訝的是,如果一個名字同時以雙下劃線開始和結束,則不會應用名稱修飾。 由雙下劃線前綴和後綴包圍的變數不會被Python解釋器修改:

class PrefixPostfixTest:
   def __init__(self):
       self.__bam__ = 42

>>> PrefixPostfixTest().__bam__
42

Python保留了有雙前導和雙末尾下劃線的名稱,用於特殊用途。

__init__是用來在初始化類的對象時被調用,同時可以傳入一些參數。
__call__用來在調用該對象時被觸發。

【表格來自//blog.csdn.net/linglongbayinhe/article/details/84848599

魔法方法 含義
基本的魔法方法
__ new__(cls[, …]) 1. __ new__ 是在一個對象實例化的時候所調用的第一個方法 2. 它的第一個參數是這個類,其他的參數是用來直接傳遞給 __ init__ 方法 3. __ new__ 決定是否要使用該 __ init__ 方法,因為 __ new__ 可以調用其他類的構造方法或者直接返回別的實例對象來作為本類的實例,如果 __ new__ 沒有返回實例對象,則 __ init__ 不會被調用 4. __ new__ 主要是用於繼承一個不可變的類型比如一個 tuple 或者 string
__ init__(self[, …]) 構造器,當一個實例被創建的時候調用的初始化方法
__ del__(self) 析構器,當一個實例被銷毀的時候調用的方法
__ call__(self[, args…]) 允許一個類的實例像函數一樣被調用:x(a, b) 調用 x.__ call__(a, b)
__ len__(self) 定義當被 len() 調用時的行為
__ repr__(self) 定義當被 repr() 調用時的行為
__ str__(self) 定義當被 str() 調用時的行為
__ bytes__(self) 定義當被 bytes() 調用時的行為
__ hash__(self) 定義當被 hash() 調用時的行為
__ bool__(self) 定義當被 bool() 調用時的行為,應該返回 True 或 False
__ format__(self, format_spec) 定義當被 format() 調用時的行為
有關屬性
__ getattr__(self, name) 定義當用戶試圖獲取一個不存在的屬性時的行為
__ getattribute__(self, name) 定義當該類的屬性被訪問時的行為
__ setattr__(self, name, value) 定義當一個屬性被設置時的行為
__ delattr__(self, name) 定義當一個屬性被刪除時的行為
__ dir__(self) 定義當 dir() 被調用時的行為
__ get__(self, instance, owner) 定義當描述符的值被取得時的行為
__ set__(self, instance, value) 定義當描述符的值被改變時的行為
__ delete__(self, instance) 定義當描述符的值被刪除時的行為
比較操作符
__ lt__(self, other) 定義小於號的行為:x < y 調用 x.__ lt__(y)
__ le__(self, other) 定義小於等於號的行為:x <= y 調用 x.__ le__(y)
__ eq__(self, other) 定義等於號的行為:x == y 調用 x.__ eq__(y)
__ ne__(self, other) 定義不等號的行為:x != y 調用 x.__ ne__(y)
__ gt__(self, other) 定義大於號的行為:x > y 調用 x.__ gt__(y)
__ ge__(self, other) 定義大於等於號的行為:x >= y 調用 x.__ ge__(y)
算數運算符
__ add__(self, other) 定義加法的行為:+
__ sub__(self, other) 定義減法的行為:-
__ mul__(self, other) 定義乘法的行為:*
__ truediv__(self, other) 定義真除法的行為:/
__ floordiv__(self, other) 定義整數除法的行為://
__ mod__(self, other) 定義取模演算法的行為:%
__ divmod__(self, other) 定義當被 divmod() 調用時的行為
__ pow__(self, other[, modulo]) 定義當被 power() 調用或 ** 運算時的行為
單下劃線:_

按照習慣,有時候單個獨立下劃線是用作一個名字,來表示某個變數是臨時的或無關緊要的。

例如,在下面的循環中,我們不需要訪問正在運行的索引,我們可以使用「_」來表示它只是一個臨時值:

>>> for _ in range(32):
...    print('Hello, World.')

在下面的程式碼示例中,我將汽車元組拆分為單獨的變數,但我只對顏色和里程值感興趣。 但是,為了使拆分表達式成功運行,我需要將包含在元組中的所有值分配給變數。 在這種情況下,「_」作為佔位符變數可以派上用場:

>>> car = ('red', 'auto', 12, 3812.4)
>>> color, _, _, mileage = car

>>> color
'red'
>>> mileage
3812.4
>>> _
12

除了用作臨時變數之外,「_」是大多數Python REPL中的一個特殊變數,它表示由解釋器評估的最近一個表達式的結果。

這樣就很方便了,比如你可以在一個解釋器會話中訪問先前計算的結果,或者,你是在動態構建多個對象並與它們交互,無需事先給這些對象分配名字:

>>> 20 + 3
23
>>> _
23
>>> print(_)
23

>>> list()
[]
>>> _.append(1)
>>> _.append(2)
>>> _.append(3)
>>> _
[1, 2, 3]

//pic3.zhimg.com/v2-cbc5c6037101c7d33cf0acd9f00a8cfa_b.jpg

 
v2-cbc5c6037101c7d33cf0acd9f00a8cfa_b.jpg