深入學習Django源碼基礎3 - python提供的對象默認方法

詳細內容看這裏A Guide to Python's Magic Methods

這裏也有1篇中文的翻譯部分https://pycoders-weekly-chinese.readthedocs.org/en/latest/issue6/a-guide-to-pythons-magic-methods.html

把python object提供的默認重載方法做了分類


1:構造和析構

__new__(cls, [...) 創造類

__init__(self, [...)初始化

__del__(self)刪除類

演示代碼

from os.path import join

class FileObject:
    '''Wrapper for file objects to make sure the file gets closed on deletion.'''

    def __init__(self, filepath='~', filename='sample.txt'):
        # open a file filename in filepath in read and write mode
        self.file = open(join(filepath, filename), 'r+')

    def __del__(self):
        self.file.close()
        del self.file

2:自定義類的操作符比較運算

也就是 == >= 此類

__cmp__(self, other)比較

__eq__(self, other)==

__ne__(self, other)!=

__lt__(self, other)<

__gt__(self, other)>

__le__(self, other)<=

__ge__(self, other)>=

演示代碼

class Word(str):
    '''Class for words, defining comparison based on word length.'''

    def __new__(cls, word):
        # Note that we have to use __new__. This is because str is an immutable
        # type, so we have to initialize it early (at creation)
        if ' ' in word:
            print "Value contains spaces. Truncating to first space."
            word = word[:word.index(' ')] # Word is now all chars before first space
        return str.__new__(cls, word)

    def __gt__(self, other):
        return len(self) > len(other)
    def __lt__(self, other):
        return len(self) < len(other)
    def __ge__(self, other):
        return len(self) >= len(other)
    def __le__(self, other):
        return len(self) <= len(other)

3:數值運算類

這裏不列舉


4:描述類

常見

__str__(self)

__repr__(self)

__unicode__(self)


5:屬性操作

__getattr__(self, name)

__setattr__(self, name, value)

__delattr__


6:自定義序列操作

__len__(self)長度

__getitem__(self, key)

__setitem__(self, key, value)

__delitem__(self, key)

__iter__(self)迭代器

__reversed__(self)反向

__contains__(self, item)

__missing__(self, key)子類繼承時候忽略

演示代碼

class FunctionalList:
    '''A class wrapping a list with some extra functional magic, like head,
    tail, init, last, drop, and take.'''

    def __init__(self, values=None):
        if values is None:
            self.values = []
        else:
            self.values = values

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

    def __getitem__(self, key):
        # if key is of invalid type or value, the list values will raise the error
        return self.values[key]

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

    def __delitem__(self, key):
        del self.values[key]

    def __iter__(self):
        return iter(self.values)

    def __reversed__(self):
        return FunctionalList(reversed(self.values))

    def append(self, value):
        self.values.append(value)
    def head(self):
        # get the first element
        return self.values[0]
    def tail(self):
        # get all elements after the first
        return self.values[1:]
    def init(self):
        # get elements up to the last
        return self.values[:-1]
    def last(self):
        # get last element
        return self.values[-1]
    def drop(self, n):
        # get all elements except first n
        return self.values[n:]
    def take(self, n):
        # get first n elements
        return self.values[:n]

7:反射

用來檢查類型

__instancecheck__(self, instance)

__subclasscheck__(self, subclass)


8:函數化

__call__(self, [args...])


9:上下文管理

__enter__(self)

__exit__(self, exception_type, exception_value, traceback)


10:抽象類

http://docs.python.org/2/library/abc.html


11:綁定的描述符

__get__(self, instance, owner)

__set__(self, instance, value)

__delete__(self, instance)

演示代碼

class Meter(object):
    '''Descriptor for a meter.'''

    def __init__(self, value=0.0):
        self.value = float(value)
    def __get__(self, instance, owner):
        return self.value
    def __set__(self, instance, value):
        self.value = float(value)

class Foot(object):
    '''Descriptor for a foot.'''

    def __get__(self, instance, owner):
        return instance.meter * 3.2808
    def __set__(self, instance, value):
        instance.meter = float(value) / 3.2808

class Distance(object):
    '''Class to represent distance holding two descriptors for feet and
    meters.'''
    meter = Meter()
    foot = Foot()

12:拷貝

__copy__(self)

__deepcopy__(self, memodict={})深拷貝


13:存儲與提取

__getinitargs__(self)

__getnewargs__(self)

__getstate__(self)

__setstate__(self, state)

__reduce__(self)

__reduce_ex__(self)

import time

class Slate:
    '''Class to store a string and a changelog, and forget its value when
    pickled.'''

    def __init__(self, value):
        self.value = value
        self.last_change = time.asctime()
        self.history = {}

    def change(self, new_value):
        # Change the value. Commit last value to history
        self.history[self.last_change] = self.value
        self.value = new_value
        self.last_change = time.asctime()

    def print_changes(self):
        print 'Changelog for Slate object:'
        for k, v in self.history.items():
            print '%s\t %s' % (k, v)

    def __getstate__(self):
        # Deliberately do not return self.value or self.last_change.
        # We want to have a "blank slate" when we unpickle.
        return self.history

    def __setstate__(self, state):
        # Make self.history = state and last_change and value undefined
        self.history = state
        self.value, self.last_change = None, None

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章