【讀書筆記】深入理解Python特性(三)

目錄

1. 對象轉換爲字符串

2. 淺複製和深複製

3. 用抽象基類避免繼承錯誤

4. namedtuple


1. 對象轉換爲字符串

  • 在print對象的時候會調用對象的__str__方法,在把對象作爲表達式調用的時候會調用對象的__repr__方法。
  • 可以使用內置的str()和repr()方法來顯示調用__str__和__repr__以更明確地表達意圖。
  • __str__()側重於面向用戶的輸出可讀性,__repr__側重於面向開發人員的調試友好性。
  • 如果沒有__str__,需要__str__時會用__repr__替代。

2. 淺複製和深複製

  • list/set/dict創建的是淺副本,利用=也是創建的淺副本
  • copy.cpoy()和copy.deepcopy()可以進行淺複製和深複製

3. 用抽象基類避免繼承錯誤

  • 爲了強制派生類實現基類的方法,通常使用如下Python慣用手法:
class Base:
    def foo(self):
        raise NotImplementedError()

    def bar(self):
        raise NotImplementedError()

class Concrete(Base):
    def foo(self):
        return 'foo() called'

    # 忘記重載bar()了
    # def bar(self):
    #     return 'bar() called'

這種方法有兩個問題:1. 實例化Base不會報錯;2.實例化Concrete不會報錯,只有調用缺失的bar方法纔會報錯

使用abc模塊來定義抽象基類可以解決這個問題

from abc import ABCMeta, abstractmethod

class Base(metaclass=ABCMeta):
    @abstractmethod
    def foo(self):
        pass
    @abstractmethod
    def bar(self):
        pass

class Concrete(Base):
    def foo(self):
        pass

    # 忘記重載bar()了
    # def bar(self):
    #     return 'bar() called'

實例化Concrete會報錯:

>>> c = Concrete()
TypeError:
"Can't instantiate abstract class Concrete
with abstract method bar"

4. namedtuple

  • namedtuple的定義和使用
from collections import namedtuple
Car = namedtuple('Car', ['color', 'mileage'])
my_car = Car('red', 113465)
ur_car = Car(color='blue', mileage=1.3)
print my_car.color # 'red'
print ur_car.mileage # 1.3
  • namedtuple適合在Python中以節省內存的方式快速手動定義一個不可變的類。
  • namedtuple的子類擴展

方法擴展

from collections import namedtuple
Car = namedtuple('Car', ['color', 'mileage'])

# 添加新方法和屬性
class MyCar(Car):
    def hexcolor(self):
        if self.color == 'red':
            return '#ff0000'
        else:
            return '#000000'
  

上面的子類雖然可以通過self.property的方法添加屬性,但是不會出現在tuple的屬性列表裏面,要擴展tuple屬性必須使用基類元組的_fields方法:

from collections import namedtuple
Car = namedtuple('Car', ['color', 'mileage'])
MyCar = namedtuple('MyCar', Car._fields + ('charge',))
  • 一些內置的輔助方法:mycar._asdict()/mycar._replace(color='blue')/Car._make(['red', 999])
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章