1. 程式人生 > >Python的魔術方法總結

Python的魔術方法總結

魔術方法:再不需要程式設計師定義,本身就存在類中的方法就是魔術方法。

魔術方法通常都長這樣:__名字__。

1.__str__和__repr__

為了方便記憶看如下列子

class Course:
    def __init__(self,name,period,price,teacher):
        self.name= name
        self.period = period
        self.price = price
        self.teacher = teacher

    def __str__(self):
        
return 'str : %s %s %s %s' % (self.name, self.period, self.price, self.teacher) def __repr__(self): return 'repr : %s %s %s %s' % (self.name, self.period, self.price, self.teacher) course_lst = [] python = Course('python','6 month',29800,'boss jin') course_lst.append(python) linux
= Course('linux','5 month',25800,'oldboy') course_lst.append(linux) for id,course in enumerate(course_lst,1): # print('%s %s %s %s %s'%(id,course.name,course.period,course.price,course.teacher)) print(id,course) print('%s %s'%(id,course)) print(str(course)) print(repr(course))
print('%r'%course)
__str__,__repr__

__str__觸發條件:

1.當你列印一個物件的時候觸發

2.當你使用%格式化的時候觸發

3.str強轉資料型別的時候觸發

__repr__:

1.__repr__是__str__的備胎

2.有__str__的時候執行__str__,沒有實現__str__的時候,執行__repr__

3.repr(obj)內建函式對應的結果是__repr__的返回值

4.當你使用%r的格式化的時候 觸發__repr__

2.__new__

在init之前,例項化物件的第一步是__new__建立了一個空間

class Foo:
    def __init__(self):  # 初始化方法
        print('執行了init')

    def __new__(cls, *args, **kwargs):  # 構造方法
        # object.__new__(cls)
        print('執行了new')
        return object.__new__(cls)


obj = Foo()

創造一個物件比喻成捏小人

new是把小人捏出來

init給小人穿衣服

應用:建立單例模式

class Foo:
    __instance = None

    def __init__(self, name, age):  # 初始化方法
        self.name = name
        self.age = age
        self.lst = [name]

    def __new__(cls, *args, **kwargs):  # 構造方法
        if cls.__instance is None:
            cls.__instance = object.__new__(cls)
        return cls.__instance


obj1 = Foo('alex', 20)
obj2 = Foo('egon', 22)
abc1 = Foo('cao', 33)
print(obj1.lst, obj2.lst, abc1.lst)
單列模式

 3.__del__

物件的__del__是物件在被gc消除回收的時候起作用的一個方法,它的執行一般也就意味著物件不能夠繼續引用。

看如下列子:

class Foo:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.file = open('file', mode='w')

    def write(self):
        self.file.write('sjahgkldhgl')

    def __del__(self):  # 析構方法 : 在刪除這個類建立的物件的時候會先觸發這個方法,再刪除物件
        # 做一些清理工作,比如說關閉檔案,關閉網路的連結,資料庫的連結
        self.file.close()
        print('執行del了')


f = Foo('alex', 20)
print(f)
__del__

4.__len__

如果一個類表現得像一個list,要獲取有多少個元素,就得用 len() 函式。

要讓 len() 函式工作正常,類必須提供一個特殊方法__len__(),它返回元素的個數。

class A:
    def __init__(self):
        self.a = 1
        self.b = 2
    def __len__(self):
        return len(self.__dict__)
a = A()
print(len(a))
print(a.__dict__)

菲波那切數列

# 菲波那切數列
# class Fib(object):
#     def __init__(self, num):
#         a, b, L = 0, 1, []
#         for n in range(num):
#             L.append(a)
#             a, b = b, a + b
#         self.numbers = L
#
#     def __str__(self):
#         return str(self.numbers)
#
#     # __repr__ = __str__
#
#     def __len__(self):
#         return len(self.numbers)
#
#
# f = Fib(10)
# print(f)
# print(len(f))
菲波那切數列

5.__eq__

__eq__ 當判斷兩個物件的值是否相等時,觸發此方法.

class Staff:
    def __init__(self,name,sex):
        self.name = name
        self.sex = sex
    def __eq__(self, other):
        return self.__dict__ == other.__dict__
alex = Staff('alex','不詳')
alex2 = Staff('alex','不詳')
alex22 = Staff('alex2','female')
print(alex == alex2)  # alex.__eq__(alex2)
print(alex2 == alex22)

6.__call__

物件後面加括號,觸發執行。

class Foo:

    def __init__(self):
        pass
    
    def __call__(self, *args, **kwargs):

        print('__call__')


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

7.__hash__

# 當一個物件的類中有"__hash__"這個方法時, 那麼這個物件就可以執雜湊計算

# 前提是要雜湊的值是可雜湊的. 雜湊的不是物件, 而是可以通過物件直接執行"hash(obj)"

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

    def __hash__(self):
        return hash(str(self.a)+str(self.b))
a = A()
print(hash(a))

8.item系列

__getitem__,__setitem,__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
    def __delitem__(self, key):
        print('del obj[key]時,我執行')
        self.__dict__.pop(key)
    def __delattr__(self, item):
        print('del obj.key時,我執行')
        self.__dict__.pop(item)

f1=Foo('sb')
f1['age']=18
f1['age1']=19
del f1.age1
del f1['age']
f1['name']='alex'
print(f1.__dict__)
item系列