国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Python魔術(shù)方法

這篇具有很好參考價(jià)值的文章主要介紹了Python魔術(shù)方法。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

Python實(shí)用教程_spiritx的博客-CSDN博客

什么是魔術(shù)方法?

所有以雙下劃線__包起來(lái)的方法,統(tǒng)稱為Magic Method(魔術(shù)方法),它是一種的特殊方法,普通方法需要調(diào)用,而魔術(shù)方法不需要顯示調(diào)用就可以執(zhí)行。

魔術(shù)方法在類或?qū)ο蟮哪承┦录霭l(fā)后會(huì)自動(dòng)執(zhí)行,讓類具有神奇的“魔力”。如果希望根據(jù)自己的程序定制自己特殊功能的類,那么就需要對(duì)這些方法進(jìn)行重寫。

常見(jiàn)的魔術(shù)方法

__init__(self)

初始化方法

觸發(fā)機(jī)制:實(shí)例化對(duì)象之后立即觸發(fā)
參數(shù):至少有一個(gè)self,接收當(dāng)前對(duì)象,其他參數(shù)根據(jù)需要進(jìn)行定義
返回值:無(wú)
作用:初始化對(duì)象的成員

# __init__示例
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

p = Point(1, 2)
print(p.x, p.y)  # 輸出: 1 2

__new__(cls)

構(gòu)造方法

觸發(fā)時(shí)機(jī): 實(shí)例化對(duì)象時(shí)自動(dòng)觸發(fā)(在__init__之前觸發(fā))
參數(shù):至少一個(gè)cls 接收當(dāng)前類,其他參數(shù)根據(jù)初始化方法參數(shù)決定
返回值:必須返回一個(gè)對(duì)象實(shí)例,沒(méi)有返回值,則實(shí)例化對(duì)象的結(jié)果為None
作用:實(shí)例化對(duì)象
注意:實(shí)例化對(duì)象是Object類底層實(shí)現(xiàn),其他類繼承了Object的__new__才能夠?qū)崿F(xiàn)實(shí)例化對(duì)象。

class Person(object):
    def __init__(self):
        print('__init__(): 我也被調(diào)用啦~')

    def __new__(cls, *args, **kwargs):  # 重寫后,不再創(chuàng)建對(duì)象
        print('__new__(): 哈哈我被調(diào)用啦~')


>>> per = Person()
__new__(): 哈哈我被調(diào)用啦~
>>> print(per)
None

class Person(object):
    def __init__(self):
        print('__init__(): 我也被調(diào)用啦~')

    def __new__(cls, *args, **kwargs): 
        print('__new__(): 哈哈我被調(diào)用啦~')
        ret = super().__new__(cls)  # 調(diào)用父類object的__new__方法創(chuàng)建對(duì)象
        return ret


>>> per = Person()
__new__(): 哈哈我被調(diào)用啦~
__init__(): 我也被調(diào)用啦~
>>> print(per)
<__main__.Person object at 0x0000020FA3892848>
class Test:
    def __new__(cls, *args, **kwargs):
        print("我是__new__方法")
        obj = object.__new__(cls)
        print(obj)
        return obj

    def __init__(self):
        print(self)
        print("我是__init__方法")


if __name__ == '__main__':
    a = Test()
    
-------輸出結(jié)果---------
我是__new__方法
<__main__.Test object at 0x123902f70>
<__main__.Test object at 0x123902f70>
我是__init__方法

上面示例會(huì)發(fā)現(xiàn):
1)__new__魔術(shù)方法返回的就是self的內(nèi)存地址;
2)如果不在__new__方法里面調(diào)object的__new__方法就不會(huì)創(chuàng)建對(duì)象,__init__不會(huì)被執(zhí)行;
3)如果不在__new__方法里面return創(chuàng)建好的對(duì)象,__init__不會(huì)被執(zhí)行;

事實(shí)上,當(dāng)我們理解了new方法后,我們還可以利用它來(lái)做一些其他有趣的事情,比如實(shí)現(xiàn) 設(shè)計(jì)模式中的 單例模式(singleton)

依照Python官方文檔的說(shuō)法,new方法主要是當(dāng)你繼承一些不可變的class時(shí)(比如int, str, tuple), 提供給你一個(gè)自定義這些類的實(shí)例化過(guò)程的途徑。還有就是實(shí)現(xiàn)自定義的metaclass

這個(gè)方法我們一般很少定義,不過(guò)我們?cè)谝恍╅_(kāi)源框架中偶爾會(huì)遇到定義這個(gè)方法的類。實(shí)際上,這才是"真正的構(gòu)造方法",它會(huì)在對(duì)象實(shí)例化時(shí)第一個(gè)被調(diào)用,然后再調(diào)用init,它們的區(qū)別主要如下:

  • new的第一個(gè)參數(shù)是cls,而init的第一個(gè)參數(shù)是self
  • new返回值是一個(gè)實(shí)例,而init沒(méi)有任何返回值,只做初始化操作
  • new由于是返回一個(gè)實(shí)例對(duì)象,所以它可以給所有實(shí)例進(jìn)行統(tǒng)一的初始化操作

由于new優(yōu)先于init調(diào)用,且返回一個(gè)實(shí)例,所以我們可以利用這種特性,每次返回同一個(gè)實(shí)例來(lái)實(shí)現(xiàn)一個(gè)單例類:



?

__del__(self)

析構(gòu)方法

觸發(fā)時(shí)機(jī):當(dāng)該類對(duì)象被銷毀時(shí),自動(dòng)觸發(fā)
參數(shù):一個(gè)self,接受當(dāng)前對(duì)象
返回值:無(wú)
作用:關(guān)閉或釋放對(duì)象創(chuàng)建時(shí)資源
注意:del不一定會(huì)觸發(fā)當(dāng)前方法,只有當(dāng)前對(duì)象沒(méi)有任何變量引用時(shí)才會(huì)觸發(fā)

class Cat:
    def eat(self):
        print("我嘎嘎能吃")

    def __del__(self):
        print("ohohoh,我被銷毀了”)

print("<=======start======>")
cat1 = Cat()
print("<=======ends======>”)

‘’‘
<=======start======>
<=======ends======>
ohohoh,我被銷毀了
’‘’

出現(xiàn)上面現(xiàn)象的原因是在沒(méi)有手動(dòng)執(zhí)行del的情況下,程序執(zhí)行結(jié)束后自動(dòng)觸發(fā)析構(gòu)方法。

繼續(xù),現(xiàn)在加一個(gè)實(shí)例化,并且我們delcat1:

cat1 = Cat()
cat2 = cat1
print("<=======start======>")
del cat1
print("<=======ends======>”)

‘’’
<=======start======>
<=======ends======>
ohohoh,我被銷毀了
’‘’

既然我們?cè)趕tart與end中間刪除了cat1,為啥程序還是在執(zhí)行完后觸發(fā)析構(gòu)方法?這主要是因?yàn)閏at2還在繼續(xù)占用cat1的內(nèi)存地址,所以會(huì)在cat2執(zhí)行完畢后觸發(fā)析構(gòu)方法。

只要同時(shí)刪除cat1和cat2,內(nèi)存地址沒(méi)有指向的值,這塊內(nèi)存被釋放就會(huì)觸發(fā)析構(gòu)方法:

cat1 = Cat()
cat2 = cat1
print("<=======start======>")
del cat1
del cat2
print("<=======ends======>”)

‘’’
<=======start======>
ohohoh,我被銷毀了
<=======ends======>
’’’

__call__(self)

可調(diào)用對(duì)象魔術(shù)方法

觸發(fā)時(shí)機(jī):將對(duì)象當(dāng)作函數(shù)調(diào)用時(shí)觸發(fā),方式: 對(duì)象()
參數(shù):至少一個(gè)self接收對(duì)象,其余根據(jù)調(diào)用時(shí)參數(shù)決定
返回值:根據(jù)情況而定
作用:可以將復(fù)雜的步驟進(jìn)行合并操作,減少調(diào)用的步驟,方便使用
注意:無(wú)

class A(object):
    def __call__(self, *args, **kwargs):
        print('call....')


a = A()
a()  # 自動(dòng)調(diào)用__call__()

class Fibonacci(object):
    def __call__(self, num):
        a, b = 1, 1
        lst = []
        if num <= 2:
            lst.append(a)
            lst.append(b)
        else:
            for i in range(num):
                lst.append(a)
                a, b = b, a + b
        return lst


>>> f = Fibonacci()
>>> print(f(5))
[1, 1, 2, 3, 5]

__str__(self)

需要對(duì)象轉(zhuǎn)換為string時(shí),python都會(huì)默認(rèn)調(diào)用該魔法方法,如print的時(shí)候,與字符串進(jìn)行+運(yùn)算的時(shí)候,凡是需要進(jìn)行隱示類型轉(zhuǎn)換為字符串的地方,都會(huì)自動(dòng)調(diào)用該方法。該方法返回一個(gè)字符串:

class Dog(object):
    def __init__(self,name):#self 是對(duì)象
        #對(duì)象.屬性名 = 屬性值
        self.name = name

    def __str__(self):
        #必須返回一個(gè)字符串
        return f"小狗的名字是{self.name}"
dog1 = Dog('aha')

print(dog1)
#str = 'Hello!' + dog1; #會(huì)提示TypeError
str = 'Hello!' + str(dog1);
print(f'{str=}’)

‘’'
小狗的名字是aha
str='Hello!小狗的名字是aha’
‘''

__repr__(self)

函數(shù)str() 用于將值轉(zhuǎn)化為適于人閱讀的形式,而repr() 轉(zhuǎn)化為供解釋器讀取的形式,某對(duì)象沒(méi)有適于人閱讀的解釋形式的話,str() 會(huì)返回與repr(),所以print展示的都是str的格式。

我們經(jīng)常會(huì)直接輸出類的實(shí)例化對(duì)象.

class Coo:
    def __init__(self):
        self.name = ""
        self.add = "python.org"
    def __repr__(self):
        return "[name="+ self.name +",add=" + self.add +"]"
co = Coo()
print(co)

‘’'
[name=,add=python.org]
‘''

由此可見(jiàn),__repr__() 方法是類的實(shí)例化對(duì)象用來(lái)做“自我介紹”的方法,默認(rèn)情況下,它會(huì)返回當(dāng)前對(duì)象的“類名+object at+內(nèi)存地址”,而如果對(duì)該方法進(jìn)行重寫,可以為其制作自定義的自我描述信息。

__repr____str__這兩個(gè)方法都是用于顯示的,__str__是面向用戶的,而__repr__面向程序員。

  • 打印操作會(huì)首先嘗試__str__和str內(nèi)置函數(shù)(print運(yùn)行的內(nèi)部等價(jià)形式),它通常應(yīng)該返回一個(gè)友好的顯示。
  • __repr__用于所有其他的環(huán)境中:用于交互模式下提示回應(yīng)以及repr函數(shù),如果沒(méi)有使用__str__,會(huì)使用print和str。它通常應(yīng)該返回一個(gè)編碼字符串,可以用來(lái)重新創(chuàng)建對(duì)象,或者給開(kāi)發(fā)者詳細(xì)的顯示。

當(dāng)我們想所有環(huán)境下都統(tǒng)一顯示的話,可以重構(gòu)__repr__方法;當(dāng)我們想在不同環(huán)境下支持不同的顯示,例如終端用戶顯示使用__str__,而程序員在開(kāi)發(fā)期間則使用底層的__repr__來(lái)顯示,實(shí)際上__str__只是覆蓋了__repr__以得到更友好的用戶顯示。

# __str__和__repr__示例
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return f"{self.name} is {self.age} years old"

    def __repr__(self):
        return f"Person('{self.name}', {self.age})"

p = Person("Alice", 25)
print(str(p))  # 輸出: Alice is 25 years old
print(repr(p))  # 輸出: Person('Alice', 25)

__del__(self)

析構(gòu)函數(shù),對(duì)象在內(nèi)存中被銷毀刪除的時(shí)候會(huì)自動(dòng)調(diào)用__del__?方法。

會(huì)在以下兩個(gè)場(chǎng)景被調(diào)用:

1、程序代碼運(yùn)行結(jié)束,在程序運(yùn)行過(guò)程中,創(chuàng)建的所有對(duì)象和變量都會(huì)被刪除銷毀

2、使用del變量,將這個(gè)對(duì)象的引用計(jì)數(shù)變?yōu)?,會(huì)自動(dòng)調(diào)用del方法

class Star(object):
    def __init__(self, name, movie):
        self.name = name  # 成員屬性 明星姓名
        self.movie = movie  # 成員屬性 明星的電影

    # 成員方法
    def playing(self):
        print(f"{self.name} 出演了電影 {self.movie} !")

    def __str__(self):
        # 打印對(duì)象時(shí)顯示,
        return f"{self.name} 是我的偶像,我非常喜歡他的電影 {self.movie}"

    def __del__(self):
        # 刪除對(duì)象時(shí)顯示
        print(f"我現(xiàn)在不喜歡 {self.name} 了")


s1 = Star('周星馳', '大話西游')
print(s1)
del s1
s2 =Star('周慧敏', '賭圣風(fēng)云')
print(s2)
print('---game over—')

‘’'
周星馳 是我的偶像,我非常喜歡他的電影 大話西游
我現(xiàn)在不喜歡 周星馳 了
周慧敏 是我的偶像,我非常喜歡他的電影 賭圣風(fēng)云
---game over--
我現(xiàn)在不喜歡 周慧敏 了
‘''

__len__(self)

len(obj)函數(shù)調(diào)用時(shí),對(duì)象會(huì)自動(dòng)調(diào)用__len()__方法

import collections
card = collections.namedtuple('card', ["rank", 'suit'])
class FrenchDeck:
    ranks = [ str(n) for n in range(2, 11)] + list("JQKA")
    suits = 'spades diamonds clubs hearts'.split()

    def __init__(self):
        self._cards = [card(rank, suit) for suit in self.suits for rank in self.ranks]

    def __len__(self):
        return len(self._cards)


fd = FrenchDeck()
print('len(fd)=', len(fd))   # 可以直接使用len函數(shù)查看fd對(duì)象的長(zhǎng)度 52

__getitem__(self,item)

擁有此方法的對(duì)象可以通過(guò)的使用列表的形式進(jìn)行對(duì)象操作,如:切片,下標(biāo)取值.

import collections
card = collections.namedtuple('card', ["rank", 'suit'])
class FrenchDeck:
    ranks = [ str(n) for n in range(2, 11)] + list("JQKA")
    suits = 'spades diamonds clubs hearts'.split()

    def __init__(self):
        self._cards = [card(rank, suit) for suit in self.suits for rank in self.ranks]

    def __len__(self):
        return len(self._cards)

    def __getitem__(self, item):
        return self._cards[item]


fd = FrenchDeck()
print('fd[0]=', fd[0])  # 可以直接使用下表取值
for i in range(0, len(fd)):
    print(fd[i])

特別注意,雖然可以通過(guò)循環(huán)的形式取出對(duì)象中值,但并不代表它是一個(gè)可迭代對(duì)象,即使你在方法中返回的是字符串也可以循環(huán),不過(guò)字符串循環(huán)會(huì)一直無(wú)限循環(huán)下去,直到你手動(dòng)停止。主要原因是,因?yàn)樵谑褂肙bj[key]時(shí),python解釋器自動(dòng)幫你調(diào)用了__getitem__(self,item)方法,所以只要不使用item這個(gè)參數(shù),無(wú)論你傳什么參數(shù)都不會(huì)報(bào)錯(cuò),返回什么值是有你決定的.

>>> isinstance(fd, collections.Iterable)
False

__cmp__(self,other)

用實(shí)例自身self和傳入的實(shí)例other進(jìn)行比較,如果self應(yīng)該排在前面,就返回 -1,如果other應(yīng)該排在前面,就返回1,如果兩者相當(dāng),返回 0。

最后可以用list.sort函數(shù)或者sorted函數(shù)來(lái)實(shí)現(xiàn)排序。

class Student(object):
    def __init__(self):
        self.grade = 0
    def __cmp__(self,other):
        if self.grade<other.grade:
            return -1
        elif self.grade>other.grade:
            return 1
        else:
            return 0

__bool__(self)

觸發(fā)時(shí)機(jī): 使用bool(對(duì)象)的時(shí)候觸發(fā)
參數(shù):一個(gè)self接收對(duì)象
返回值:必須是布爾值
作用:根據(jù)實(shí)際情況決定,可以作為快捷方式使用
注意:僅適合于返回布爾值的操作

class A:
    print("__bool__和__len__都未定義,bool調(diào)用恒為True")

print(bool(A()))
#__bool__和__len__都未定義,bool調(diào)用恒為True
#True

class B:
    def __bool__(self):
        print("__bool__返回False,bool調(diào)用恒為False")
        return False

print(bool(B()))
#__bool__返回False,bool調(diào)用恒為False
#False


class C:
    def __len__(self):
        print("__bool__未定義,找到__len__,__len__返回值非0,bool調(diào)用恒為True")
        return 1


print(bool(C()))
#__bool__未定義,找到__len__,__len__返回值非0,bool調(diào)用恒為True
#True

# 定義空字典
a = {}
# 定義空列表
b = []
# 定義空元組
c = ()

# 以后判斷這個(gè)3種數(shù)據(jù)類型是否有返回值直接通過(guò)bool方法來(lái)判斷
if not bool(a):
    print("a為空字典")

if not bool(b):
    print("b為空列表")

if not bool(c):
    print("c為空元組")

‘’'
a為空字典
b為空列表
c為空元組
‘''

__format__(self)

觸發(fā)時(shí)機(jī):使用字符串.format(對(duì)象)時(shí)候觸發(fā)
參數(shù):一個(gè)self接收對(duì)象,一個(gè)參數(shù)接收f(shuō)ormat的{}中的格式,例如:>5
返回值:必須是字符串
作用:設(shè)置對(duì)象可以作為format的參數(shù),并且自定義對(duì)象格式化的規(guī)則
注意:無(wú)

__hash__(self)

調(diào)用hash函數(shù)時(shí)

class A:
    def __init__(self):
        self.a = 'a'
        self.b = 'b'

    def __hash__(self):
        return 1


print(hash(A())) #1
print(hash(A())) #1


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

    def __hash__(self):
        return hash((self.name, self.age))

    def __eq__(self, other):
        if isinstance(other, Person):
            return self.name == other.name and self.age == other.age
        return False


# 創(chuàng)建對(duì)象
person1 = Person("John", 30)
person2 = Person("Alice", 25)

# 輸出哈希值
print(f"對(duì)象person1的hash值 {hash(person1)}”) #對(duì)象person1的hash值 2511066681118794660
print(f"對(duì)象person2的hash值 {hash(person2)}”) #對(duì)象person2的hash值 -7352762741811000521

# 比較對(duì)象相等性
print(f"person1和person2相等是否成立  {person1 == person2}”) #對(duì)象person2的hash值 -7352762741811000521

__add__(self,other)

實(shí)例只見(jiàn)的加法運(yùn)算

class Vector:
   def __init__(self, a, b):
      self.a = a
      self.b = b
 
   def __str__(self):
      return 'Vector (%d, %d)' % (self.a, self.b)
   
   def __add__(self,other):
      return Vector(self.a + other.a, self.b + other.b)
 
v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)

‘’’
Vector(7,8)
’‘’

運(yùn)算符魔術(shù)方法

重載運(yùn)算魔法函數(shù)定義 魔法函數(shù)說(shuō)明
__add__(self,other) 實(shí)例之間的加法運(yùn)算+
__sub__(self,other) 實(shí)例之間的減法運(yùn)算-
__mul__(self,other) 實(shí)例之間的乘法運(yùn)算*
__truediv__(self,other) 類與類之間的真除。只有from?future?import division之后它才有效/
__floordiv__(self,other) 類與類之間的浮點(diǎn)除法運(yùn)算//
__mod__(self,other) 類與類之間的取余運(yùn)算%
__pow__(self,other[,module])) 類與類之間的指數(shù)運(yùn)算**
__and__(self,other) 類與類之間的按位與運(yùn)算&
__xor__(self,other) 類與類之間的按位異或運(yùn)算^
__or__(self,other) 類與類之間的按位或運(yùn)算|
__lt__(self,other) 定義了比較操作符<
__gt__(self,other) 定義了比較操作符>
__le__(self,other) 定義了比較操作符<=
__ge__(self,other) 定義了比較操作符>=
__eq__(self,other) 定義了比較操作符==
__ne__(self,other) 定義了比較操作符!=
__setitem__(self, key, value) 使用self[nkey] = value賦值容器中的一項(xiàng)
__delitem__(self, key) 刪除self[nkey]。

例子:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        
    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)
    
    def __sub__(self, other):
        return Point(self.x - other.x, self.y - other.y)
    
    def __mul__(self, scalar):
        return Point(self.x * scalar, self.y * scalar)
    
    def __truediv__(self, scalar):
        return Point(self.x / scalar, self.y / scalar)
    
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y

p1 = Point(1, 2)
p2 = Point(3, 4)

# 加法操作
p3 = p1 + p2
print(p3.x, p3.y) # 輸出: 4, 6

# 減法操作
p4 = p1 - p2
print(p4.x, p4.y) # 輸出: -2, -2

# 乘法操作
p5 = p1 * 2
print(p5.x, p5.y) # 輸出: 2, 4

# 除法操作
p6 = p1 / 2
print(p6.x, p6.y) # 輸出: 0.5, 1.0

# 等值比較操作
print(p1 == p2) # 輸出: False
print(p1 == Point(1, 2)) # 輸出: True



# __lt__和__eq__示例
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __lt__(self, other):
        return self.age < other.age

    def __eq__(self, other):
        return self.age == other.age

p1 = Person("Alice", 25)
p2 = Person("Bob", 30)
p3 = Person("Charlie", 25)
print(p1 < p2)  # 輸出: True
print(p1 == p3)  # 輸出: True

反運(yùn)算魔術(shù)方法

反運(yùn)算魔法方法,與算術(shù)運(yùn)算符保持一一對(duì)應(yīng),不同之處就是反運(yùn)算的魔法方法多了一個(gè)“r”。當(dāng)文件左操作不支持相應(yīng)的操作時(shí)被調(diào)用。

  • radd(self, other)定義加法的行為:+
  • rsub(self, other)定義減法的行為:-
  • rmul(self, other)定義乘法的行為:*
  • rtruediv(self, other)定義真除法的行為:/
  • rfloordiv(self, other)定義整數(shù)除法的行為://
  • rmod(self, other) 定義取模算法的行為:%
  • rdivmod(self, other)定義當(dāng)被 divmod() 調(diào)用時(shí)的行為
  • divmod(a, b)把除數(shù)和余數(shù)運(yùn)算結(jié)果結(jié)合起來(lái),返回一個(gè)包含商和余數(shù)的元組(a // b, a % b)。
  • rpow(self, other[, module])定義當(dāng)被 power() 調(diào)用或 ** 運(yùn)算時(shí)的行為
  • rlshift(self, other)定義按位左移位的行為:<<
  • rrshift(self, other)定義按位右移位的行為:>>
  • rand(self, other)定義按位與操作的行為:&
  • rxor(self, other)定義按位異或操作的行為:^
  • ror(self, other)定義按位或操作的行為:|
    a + b
    這里加數(shù)是a,被加數(shù)是b,因此是a主動(dòng),反運(yùn)算就是如果a對(duì)象的__add__()方法沒(méi)有實(shí)現(xiàn)或者不支持相應(yīng)的操作,那么 Python 就會(huì)調(diào)用b的__radd__()方法。
class Nint(int):
    def __add__(self, other):
        print('__add()__')
        return int.__add__(self, other)
    def __radd__(self, other):
        print('__radd()__')
        return int.__sub__(other, self) # 注意 self 在后面

a = Nint(5)
b = Nint(3)
print(a + b)  # 8
print('####')
print(1 + b)  # -2

‘’'
__add()__
8
####
__radd()__
-2
‘''

賦值運(yùn)算符魔術(shù)方法

  • iadd(self, other)定義賦值加法的行為:+=
  • isub(self, other)定義賦值減法的行為:-=
  • imul(self, other)定義賦值乘法的行為:*=
  • itruediv(self, other)定義賦值真除法的行為:/=
  • ifloordiv(self, other)定義賦值整數(shù)除法的行為://=
  • imod(self, other)定義賦值取模算法的行為:%=
  • ipow(self, other[, modulo])定義賦值冪運(yùn)算的行為:**=
  • ilshift(self, other)定義賦值按位左移位的行為:<<=
  • irshift(self, other)定義賦值按位右移位的行為:>>=
  • iand(self, other)定義賦值按位與操作的行為:&=
  • ior(self, other)定義賦值按位或操作的行為:|=
  • ixor(self, other)定義賦值按位異或操作的行為:^=

一元運(yùn)算符魔術(shù)方法

  • neg(self)定義正號(hào)的行為:+x
  • pos(self)定義負(fù)號(hào)的行為:-x
  • abs(self)定義當(dāng)被abs()調(diào)用時(shí)的行為
  • invert(self)定義按位求反的行為:~x

屬性訪問(wèn)魔術(shù)方法

__getattr__(self, name)

定義當(dāng)用戶試圖獲取一個(gè)不存在的屬性時(shí)的行為。

觸發(fā)時(shí)機(jī):獲取不存在的對(duì)象成員時(shí)觸發(fā)
參數(shù):一個(gè)是接收當(dāng)前對(duì)象的self,一個(gè)是獲取成員名稱的字符串
返回值:必須有值
作用:為訪問(wèn)不存在的屬性設(shè)置值
注意:getattribute無(wú)論何時(shí)都會(huì)在getattr之前觸發(fā),觸發(fā)了getattribute就不會(huì)在觸發(fā)getattr了

class Base:
    n = 0
    
class Point(Base):
    z = 6
    
    def __init__(self, x, y):
        self.x = x
        self.y = y
        
    def show(self):
        print(self.x, self.y)
        
    def __getattr__(self, item):
        return item
    
>>> p1.x
4
>>> p1.z
6
>>> p1.n
0
>>> p1.t
't'

實(shí)例屬性會(huì)按照繼承關(guān)系尋找,如果找不到,就會(huì)執(zhí)行__getattr__()方法,如果沒(méi)有這個(gè)方法,就會(huì)拋出AttributeError異常標(biāo)識(shí)找不到屬性。

__getattribute__(self, name)

定義當(dāng)該類的屬性被訪問(wèn)時(shí)的行為(先調(diào)用該方法,查看是否存在該屬性,若不存在,接著去調(diào)用__getattr__)

觸發(fā)時(shí)機(jī):使用對(duì)象成員時(shí)觸發(fā),無(wú)論成員是否存在
參數(shù):1個(gè)接收當(dāng)前對(duì)象self,一個(gè)是獲取的成員的名稱字符串
返回值:必須有
作用:在具有封裝操作(私有化時(shí)),為程序開(kāi)部分訪問(wèn)權(quán)限使用

class Base:
    n = 0
    
class Point(Base):
    z = 6
    
    def __init__(self, x, y):
        self.x = x
        self.y = y
        
    def __getattr__(self, item):
        return item
    
    def __getattribute__(self, item):
        return item
     
>>> p1 = Point(4, 5)
>>> print(p1.__dict__)
__dict__
>>> print(p1.x)
x
>>> print(p1.z)
z
>>> print(p1.n)
n
>>> print(p1.t)
t
>>> print(Point.__dict__)
{'__module__': '__main__', 'z': 6, '__init__': <function Point.__init__ at 0x000001F5EB7063A8>, '__getattr__': <function Point.__getattr__ at 0x000001F5EB706558>, '__getattribute__': <function Point.__getattribute__ at 0x000001F5EB706168>, '__doc__': None}
>>> print(Point.z)
6

實(shí)例的所有的屬性訪問(wèn),第一個(gè)都會(huì)調(diào)用__getattribute__方法,它阻止了屬性的查找,該方法應(yīng)該返回值或者拋出一個(gè)AttributeError異常。

該方法的返回值將作為屬性查找的結(jié)果。
如果拋出AttributeError異常,則會(huì)直接調(diào)用__getattr__方法,因?yàn)閷傩詻](méi)有找到,__getattribute__方法中為了避免在該方法中無(wú)限遞歸,它的實(shí)現(xiàn)應(yīng)該永遠(yuǎn)調(diào)用基類的同名方法以訪問(wèn)需要的任何屬性。
需要注意的是,除非明確知道__getattrtbute__方法用來(lái)做什么,否則不要使用。
?

__setattr__(self, name, value)

定義當(dāng)一個(gè)屬性被設(shè)置時(shí)的行為

觸發(fā)時(shí)機(jī):設(shè)置對(duì)象成員值的時(shí)候觸發(fā)
參數(shù):1個(gè)當(dāng)前對(duì)象的self,一個(gè)是要設(shè)置的成員名稱字符串,一個(gè)是要設(shè)置的值
返回值:無(wú) 過(guò)程操作
作用:接管設(shè)置操作,可以在設(shè)置前之前進(jìn)行判斷驗(yàn)證等行為
注意:在當(dāng)前方法中無(wú)法使用成員=值的方式直接設(shè)置成員,否則會(huì)無(wú)限遞歸,必須借助object的設(shè)置方法來(lái)完成

class Base:
    n = 0
    
class Point(Base):
    z = 6
    
    def __init__(self, x, y):
        self.x = x
        self.y = y
        
    def show(self):
        print(self.x, self.y)
        
    def __getattr__(self, item):
        return item
    
    def __setattr__(self, key, value):
        print(key, value)
        
# --------------------------------------------------
>>> p1 = Point(4, 5)
x 4
y 5
>>> print(p1.x)
x
>>> print(p1.z)
6
>>> print(p1.n)
0
>>> print(p1.t)
t
# --------------------------------------------------
>>> p1.x = 50
>>> print(p1.x)
x
>>> print(p1.__dict__)
{}
>>> p1.__dict__['x'] = 60
>>> print(p1.__dict__)
{'x': 60}
>>> p1.x
60

__delattr__(self, name)

定義當(dāng)一個(gè)屬性被刪除時(shí)的行為

觸發(fā)時(shí)機(jī):刪除對(duì)象成員時(shí)觸發(fā)
參數(shù):一個(gè)當(dāng)前對(duì)象的self
返回值:無(wú)
作用:可以在刪除成員時(shí)進(jìn)行驗(yàn)證。

__dir__(self)

觸發(fā)時(shí)機(jī):dir(對(duì)象)的時(shí)候觸發(fā)
參數(shù):1個(gè)接收當(dāng)前對(duì)象self
返回值:必須為序列類型(列表,元組,集合等,)
作用:可以自定義成員列表的返回值

例子

class C:
    def __getattribute__(self, item):
        print('__getattribute__')
        return super().__getattribute__(item)

    def __getattr__(self, item):
        print('__getattr__')

    def __setattr__(self, key, value):
        print('__setattr__')
        super().__setattr__(key, value)

    def __delattr__(self, item):
        print('__delattr__')
        super().__delattr__(item)

c = C()
print('1-----')
c.x
# __getattribute__
# __getattr__
print('2-----')
c.x = 1
# __setattr__
print('3-----')
del c.x
# __delattr__

類型轉(zhuǎn)換魔術(shù)方法

  • __complex__ (self)定義當(dāng)被 complex() 調(diào)用時(shí)的行為(需要返回恰當(dāng)?shù)闹担?/li>
  • __int__(self) 定義當(dāng)被 int() 調(diào)用時(shí)的行為(需要返回恰當(dāng)?shù)闹担?/li>
  • __float__(self) 定義當(dāng)被 float() 調(diào)用時(shí)的行為(需要返回恰當(dāng)?shù)闹担?/li>
  • __round__(self[, n]) 定義當(dāng)被 round() 調(diào)用時(shí)的行為(需要返回恰當(dāng)?shù)闹担?/li>
  • __index(self)__ 1. 當(dāng)對(duì)象是被應(yīng)用在切片表達(dá)式中時(shí),實(shí)現(xiàn)整形強(qiáng)制轉(zhuǎn)換
  • 2. 如果你定義了一個(gè)可能在切片時(shí)用到的定制的數(shù)值型,你應(yīng)該定義 index
  • 3. 如果 index 被定義,則 int 也需要被定義,且返回相同的值

上下文相關(guān)的魔術(shù)方法

__enter__(self)

1. 定義當(dāng)使用 with 語(yǔ)句時(shí)的初始化行為
2. enter 的返回值被 with 語(yǔ)句的目標(biāo)或者 as 后的名字綁定

__exit__(self, exctype, excvalue, traceback)

1. 定義當(dāng)一個(gè)代碼塊被執(zhí)行或者終止后上下文管理器應(yīng)該做什么
2. 一般被用來(lái)處理異常,清除工作或者做一些代碼塊執(zhí)行完畢之后的日常工作

# __enter__和__exit__示例
class DatabaseConnection:
    def __init__(self, db_url):
        self.db_url = db_url

    def __enter__(self):
        self.connection = open(self.db_url)
        return self.connection

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.connection.close()

# 使用 with 語(yǔ)句打開(kāi)數(shù)據(jù)庫(kù)連接,并在結(jié)束時(shí)自動(dòng)關(guān)閉連接
with DatabaseConnection('example.db') as conn:
    # 執(zhí)行一些操作
    cursor = conn.cursor()
    cursor.execute('SELECT * FROM users')
    rows = cursor.fetchall()
    print(rows)

容器相關(guān)的魔術(shù)方法

  • __len__(self) 定義當(dāng)被 len() 調(diào)用時(shí)的行為(返回容器中元素的個(gè)數(shù))
  • __getitem__(self, key) 定義獲取容器中指定元素的行為,相當(dāng)于 self[key]
  • __setitem__(self, key, value) 定義設(shè)置容器中指定元素的行為,相當(dāng)于 self[key] = value
  • __delitem__(self, key) 定義刪除容器中指定元素的行為,相當(dāng)于 del self[key]
  • __iter__(self) 定義當(dāng)?shù)萜髦械脑氐男袨?/li>
  • __next__(self)從iterable對(duì)象中獲取下一個(gè)元素
  • __reversed__(self) 定義當(dāng)被 reversed() 調(diào)用時(shí)的行為
  • __contains__(self, item) 定義當(dāng)使用成員測(cè)試運(yùn)算符(in 或 not in)時(shí)的行為
  • __missing__字典使用__getitem__()調(diào)用時(shí),key不存在執(zhí)行該方法
# __getitem__和__setitem__示例
class MyList:
    def __init__(self, items):
        self.items = items

    def __getitem__(self, index):
        return self.items[index]

    def __setitem__(self, index, value):
        self.items[index] = value

l = MyList([1, 2, 3, 4])
print(l[2])  # 輸出: 3
l[2] = 5
print(l[2])  # 輸出: 5

# __contains__示例
class MyList:
    def __init__(self, items):
        self.items = items

    def __contains__(self, item):
        return item in self.items

l = MyList([1, 2, 3, 4])
print(2 in l)  # 輸出: True
print(5 in l)  # 輸出: False


# __iter__和__next__示例
class MyRange:
    def __init__(self, start, end):
        self.start = start
        self.end = end

    def __iter__(self):
        return self

    def __next__(self):
        if self.start >= self.end:
            raise StopIteration
        value = self.start
        self.start += 1
        return value

r = MyRange(0, 5)
for i in r:
    print(i)  # 輸出: 0 1 2 3 4

?魔法屬性

__doc__

這是一個(gè)屬性,獲取類或?qū)ο髢?nèi)部文檔。

class MyClass():
    """
        我是一個(gè)類,這里說(shuō)明一些有用的信息
    """

    def __init__(self):
        pass


print(MyClass.__doc__)
#        我是一個(gè)類,這里說(shuō)明一些有用的信息

__name__

這也是一個(gè)屬性,獲取類名或函數(shù)名?

class Class1:
    pass


class MyClass:
    def task1(self, func1):
        print(func1.__name__)


def func():
    print("我是func1函數(shù)")


>>> obj = MyClass()
>>> obj.task1(func)
func
>>> obj.task1(Class1)
Class1

__class__

獲取當(dāng)前對(duì)象獲取的類

class Class1:
    pass


>>> obj = Class1()
>>> print(obj.__class__)
<class '__main__.Class1'>
>>> print(obj.__class__.__name__)
Class1

__base__

獲取一個(gè)類直接繼承的所有父類,返回元組。

class Class1:
    pass


class Class2:
    pass


class MyClass(Class1, Class2):
    pass


>>> print(MyClass.__bases__)
(<class '__main__.Class1'>, <class '__main__.Class2'>)

__dict__

獲取類或?qū)ο蟮牡?strong>內(nèi)部成員結(jié)構(gòu)。主要用來(lái)獲取用戶自定義的屬性,以及這個(gè)屬性對(duì)應(yīng)的值。返回的是一個(gè)字典。

class MyClass():
    name1 = "Lsir"
    name2 = "Wsir"
    name3 = "Zsir"

    def task1(self):
        print("task1")

    def task2(self):
        print("tesk2")

    def task3(self):
        print("task3")


>>> print(MyClass.__dict__)
{'__module__': '__main__', 'name1': 'Lsir', 'name2': 'Wsir', 'name3': 'Zsir', 'task1': <function MyClass.task1 at 0x0000020C16385558>, 'task2': <function MyClass.task2 at 0x0000020C16385D38>, 'task3': <function MyClass.task3 at 0x0000020C16385708>, '__dict__': <attribute '__dict__' of 'MyClass' objects>, '__weakref__': <attribute '__weakref__' of 'MyClass' objects>, '__doc__': None}

dir函數(shù)做一個(gè)區(qū)分。dir函數(shù)返回的是這個(gè)對(duì)象上擁有的所有屬性,包括Python內(nèi)置的屬性和用戶自己添加的,并且只是獲取屬性名字,不會(huì)獲取這個(gè)屬性對(duì)應(yīng)的值。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-686392.html

到了這里,關(guān)于Python魔術(shù)方法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 在Python環(huán)境中運(yùn)行R語(yǔ)言的配環(huán)境實(shí)用教程

    在Python環(huán)境中運(yùn)行R語(yǔ)言的配環(huán)境實(shí)用教程

    前情提要 在做一些生物信息與醫(yī)學(xué)統(tǒng)計(jì)的工作,本來(lái)偷懶希望只靠python完成的,結(jié)果還是需要用R語(yǔ)言,倒騰了一會(huì)兒,調(diào)成功了,就記錄一下這個(gè)過(guò)程。 我的環(huán)境: win10, pycharm, R-4.3.2 首先,我們安裝R語(yǔ)言,這里給出兩個(gè)鏈接 官網(wǎng):R: The R Project for Statistical Computing 清華鏡像

    2024年01月23日
    瀏覽(18)
  • 深入理解 python 虛擬機(jī):魔術(shù)方法之?dāng)?shù)學(xué)計(jì)算

    在本篇文章當(dāng)中主要給大家介紹在 python 當(dāng)中一些常見(jiàn)的魔術(shù)方法,本篇文章主要是關(guān)于與數(shù)學(xué)計(jì)算相關(guān)的一些魔術(shù)方法,在很多科學(xué)計(jì)算的包當(dāng)中都使用到了這些魔術(shù)方法。 當(dāng)我們?cè)赑ython中定義自己的類時(shí),可以通過(guò)重寫一些特殊方法來(lái)改變對(duì)象的比較行為。這些特殊方法

    2024年02月05日
    瀏覽(18)
  • 深入理解 python 虛擬機(jī):花里胡哨的魔術(shù)方法

    在本篇文章當(dāng)中主要給大家介紹在 cpython 當(dāng)中一些比較花里胡哨的魔術(shù)方法,以幫助我們自己實(shí)現(xiàn)比較花哨的功能,當(dāng)然這其中也包含一些也非常實(shí)用的魔術(shù)方法。 在 Python 中, __hash__() 方法是一種特殊方法(也稱為魔術(shù)方法或雙下劃線方法),用于返回對(duì)象的哈希值。哈希

    2024年02月06日
    瀏覽(20)
  • Python-面向?qū)ο螅好嫦驅(qū)ο蟆⒊蓡T方法 、類和對(duì)象、構(gòu)造方法、魔術(shù)方法、封裝、繼承、類型注解、多態(tài)(抽象類(接口))

    Python-面向?qū)ο螅好嫦驅(qū)ο?、成員方法 、類和對(duì)象、構(gòu)造方法、魔術(shù)方法、封裝、繼承、類型注解、多態(tài)(抽象類(接口))

    當(dāng)前版本號(hào)[20230806]。 版本 修改說(shuō)明 20230806 初版 生活中數(shù)據(jù)的組織 學(xué)校開(kāi)學(xué),要求學(xué)生填寫自己的基礎(chǔ)信息,一人發(fā)一張白紙,讓學(xué)生自己填, 易出現(xiàn)內(nèi)容混亂 但當(dāng)改為登記表,打印出來(lái)讓學(xué)生自行填寫, 就會(huì)整潔明了 程序中數(shù)據(jù)的組織 在程序中簡(jiǎn)單使用變量來(lái)記錄學(xué)

    2024年02月14日
    瀏覽(22)
  • C++&Python&C# 三語(yǔ)言O(shè)penCV從零開(kāi)發(fā)(2):教程選擇

    C++&Python&C# 三語(yǔ)言O(shè)penCV從零開(kāi)發(fā)(2):教程選擇

    C++PythonCsharp in OpenCV OpenCV 有官方的教程和簡(jiǎn)單的視頻教程: OpenCV 官方教程 B站也有相關(guān)的視頻教學(xué) OpenCV4 C++ 快速入門視頻30講 - 系列合集 OpenCV4 C++ 課程筆記 那么選擇文本教程還是視頻教程呢?我個(gè)人建議是 視頻教程:零基礎(chǔ),一點(diǎn)都沒(méi)有接觸過(guò) 文本教程:有一定的基礎(chǔ),

    2024年01月21日
    瀏覽(29)
  • Python比較日期的實(shí)用方法

    Python比較日期的實(shí)用方法 Python是一種優(yōu)秀的編程語(yǔ)言,它具有易于學(xué)習(xí)、易于擴(kuò)展、靈活性強(qiáng)等優(yōu)點(diǎn),被廣泛應(yīng)用于各個(gè)領(lǐng)域。在Python中,日期常常是一個(gè)重要的數(shù)據(jù)類型,在實(shí)際開(kāi)發(fā)中,經(jīng)常需要比較日期的大小關(guān)系。在本文中,我們將介紹Python中比較日期的實(shí)用方法。

    2024年02月14日
    瀏覽(16)
  • 手把手QQ機(jī)器人制作教程,根據(jù)官方接口進(jìn)行開(kāi)發(fā),基于Python語(yǔ)言制作的詳細(xì)教程(更新中)

    手把手QQ機(jī)器人制作教程,根據(jù)官方接口進(jìn)行開(kāi)發(fā),基于Python語(yǔ)言制作的詳細(xì)教程(更新中)

    QQ開(kāi)放平臺(tái)官方地址:https://q.qq.com/#/app/bot QQ開(kāi)放平臺(tái)包含:QQ機(jī)器人、QQ小程序、QQ小游戲,我們這邊選擇QQ機(jī)器人。 機(jī)器人類型:設(shè)置私域機(jī)器人或者公域機(jī)器人,當(dāng)然公域機(jī)器人對(duì)于服務(wù)器的要求過(guò)高,我們這邊選擇 私域機(jī)器人 進(jìn)行開(kāi)發(fā)。 特別注意在選擇沙箱頻道的時(shí)候

    2023年04月08日
    瀏覽(28)
  • Python操作HDFS文件的實(shí)用方法

    Python操作HDFS文件的實(shí)用方法 Apache Hadoop是一個(gè)開(kāi)源的分布式計(jì)算系統(tǒng),它提供了一種高效的方式來(lái)存儲(chǔ)和處理大規(guī)模數(shù)據(jù)集。Hadoop的核心組件之一是Hadoop分布式文件系統(tǒng)(HDFS),它提供了可擴(kuò)展的存儲(chǔ)和高效的數(shù)據(jù)訪問(wèn)。 在Python中,我們可以使用hdfs庫(kù)來(lái)連接和操作HDFS。在本

    2024年02月09日
    瀏覽(10)
  • 編程界的“魔術(shù)師”:Python中的一行代碼藝術(shù)

    標(biāo)題: “成為編程界的“魔術(shù)師”:Python中的一行代碼藝術(shù)” 編程的世界中,有一種被稱為“一行代碼魔術(shù)師”的存在。他們擅長(zhǎng)用簡(jiǎn)潔、精煉的代碼實(shí)現(xiàn)復(fù)雜的功能,就像變魔術(shù)一樣令人驚嘆。 Python作為一種高級(jí)編程語(yǔ)言,其簡(jiǎn)潔明了的語(yǔ)法使得它成為“一行代碼魔術(shù)師

    2024年02月03日
    瀏覽(19)
  • 使用 Python 的支持向量回歸 (SVR):預(yù)測(cè)建模的實(shí)用方法

    介紹 : 支持向量回歸 (SVR) 是一種用于解決回歸問(wèn)題的強(qiáng)大算法。它是支持向量機(jī) (SVM) 的一部分,用于變量之間的非線性關(guān)系。 在本文中,我們將學(xué)習(xí)如何使用 python 語(yǔ)言實(shí)現(xiàn)它。 了解 SVR: SVR 的目標(biāo)是找到最適合數(shù)據(jù)點(diǎn)的超平面,同時(shí)允許誤差容限。傳統(tǒng)的回歸模型專注

    2024年02月14日
    瀏覽(21)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包