Home

abawchen's graffiti

28 Dec 2017

Python Types and Objects Part 3

Part 2 我們提到了 type、class、object 這三者之間的關係,也提到了 type 和 non-type 之間的差別。在這篇文章中,將會提到更多的 built-in types 和自定義的 class。


Built-in Types

>>> list #1
<type 'list'>
>>> list.__class__ #2
<type 'type'>
>>> list.__bases__ #3
(<type 'object'>,)
>>> tuple.__class__, tuple.__bases__ #4
(<type 'type'>, (<type 'object'>,))
>>> dict.__class__, dict.__bases__ #5
(<type 'type'>, (<type 'object'>,))
>>>
>>> mylist = [1,2,3] #6
>>> mylist.__class__ #7
<type 'list'>

#1: built-in 的 <type ‘list’> object
#2: list 的類型是 <type ‘type’>
#3: list 的 superclass 是 object
#4: tuple 的類型和 superclass 分別是 <type ‘type’> 和 object (和 list 一樣)
#5: dict 也是
#6: list 的 instance mylist
#7: mylist 的類型是 <type ‘list’>


自定義的 objects

上面是 Python built-in(內建)就有的,那如果我們想要創造自己的 object 呢?

# In Python 2.x:
class C(object): pass #1
# In Python 3.x, the explicit base class is not required, classes are # automatically subclasses of object:
class C: pass #2
class D(object): pass
class E(C, D): pass #3
class MyList(list): pass #4

#1: 建立一個新的 type
#2: 2.x 的版本千萬不要省略 superclass 的宣告
#3: 多個 bases 是允許的
#4: 也可以繼承 built-in types(但不是全部都可以)


New Objects by Instantiating

obj = object() #1
cobj = C() #2
mylist = [1,2,3] #3

#1, #2, #3: 一些創建 objects 的語法。

這邊還沒有提到有關 C() 的 type,將在之後的文章中介紹。


Q & A

Q: Python 到底是怎麼產生新的 object?
A: 根據他的 type,並且在 __new__() 和 __init__() 中實作這個 object 應該產生哪些東西的細節。可以想要成用 type 來產生的實體的 factory。

Q: 那我可以自己指定要用什麼 type 產生 instance 嗎?
A: 可以,用 __metaclass__

class MyCWithSpecialType(object):
    __metaclass__ = SpecialType

Q: 那 __metaclass__ 可以是任何 type 嗎?
A: 不行,它必須是 object 的 type 的 subclass (原文:It must be a subclass of the type of the base object),這到底是在說什麼 …。沒關係,看下面的定義。至於如何實作 __metaclass__ 在這系列中並不討論。

  • MyCWithSpecialType 的 base 是 <type ‘object’>
  • <type ‘object’> 的類型是 <type ‘type’>
  • 因此 SpecialType 必須是 <type ‘type’> 的 subclass

Q: 那如果有多個 bases,但卻沒有指定 __metaclass__,那到底會用哪個 type?
A: 好問題!如果所有 bases 的 type 都相同,那就是他了!如果都不同,且彼此之間找不到關聯,那這時候就要自己指定 __metaclass__,但 __metaclass__ 必須是所有 base 的 type 的 subclass。

Q: 那什麼時候要用到 __metaclass__?
A: 永遠不要!

Til next time,
abawchen at 20:10