學過java語言的童鞋都知道,java是一門物件導向語言,其基本思想就是一切皆物件。Python也是一樣的,甚至Python將物件導向思想貫徹地更加徹底,因為在Python中,class本身是一個物件,class例項化出來的例項也是物件,方法函式是一個物件,甚至程式碼模組都是一個物件,這是java不曾擁有的。
物件的一個重要特性就是可以被賦值給其他變數,我們說方法、函式、類都是物件,那麼,當然也具有這一特性:
def say(name='張三'):
print('I am %s' % name)
func = say
func('李四')
I am 李四
甚至函式內部還可以將函式作為返回值,注意這一特性非常重要,因為這是Python裝飾器的基礎:
def func(flag):
if flag:
def func1():
return 1
else:
def func1():
return 2
return func1
f = func(flag=True)
f()
1
再來看看類的賦值:
class Student:
def __init__(self, name='張三'):
self.name = name
print('I am %s' % name)
my_class = Student
my_class('李四')
I am 李四
<__main__.Student at 0x7ff029457910>
我們還可以繼續講類和函式放進一個list中:
lst = []
lst.append(func)
lst.append(Student)
lst[0]('王五')
I am 王五
lst[1]('王五')
I am 王五
<__main__.Student at 0x7ff0294524d0>
可見,類和函式方法都是物件。
2 class type object的關係¶
在上文中我們說過,Python中一切皆物件,class也不例外,而class就是用來生成object的物件,那麼,既然class也是一個物件,它又是誰生成的呢?沒錯,就是type,可以這麼認為,type就是用來生成class(類)的一種物件。
我們知道,Python中有一個type()方法,可以檢視傳遞的例項是有哪個類生成的:
class Person:
pass
p = Person()
type(p)
__main__.Person
可以看到,type(p)指向的是一個Person類。那麼,如果我們對Person類使用type()呢?
type(Person)
type
返回的是一個type,那麼,我們可以認為,type是生成Person類的類。type這個類物件本身又是由誰生成的呢?
type(type)
type
可知,type物件也是由type本身生成的。所以,type是最頂層的類,一切類物件都是由type生成。
物件和類是兩種不同的概念,物件是一個具體的概念,是類這個模板生成出來的。在Python中,類既擁有作為一個物件的特性,也有用物件的特性,我們可以認為,Python類中所擁有的物件的特性是由type所生成、賦予的。那麼,Python類所擁有的作為一個類的特性是誰賦予的呢?
那就是object。
在java中,任何一個沒有明確指明繼承關係的類,都繼承object類,在Python中也不例外:
class Person:
pass
呼叫類的base屬性可以檢視父類:
Person.__base__
object
在定義Person類時,我們沒有指明繼承關係,所以,預設就繼承自object類。除了自定義的類外,Python的內建型別也一樣繼承自object:
int.__base__
object
str.__base__
object
object的父類會是誰?
print(object.__base__)
None
可知,object沒有父類。
繼續,object類是不是物件呢?肯定是,因為Python無處不物件,那麼,object是哪個類例項化生成的呢?
type(object)
type
可見,object是由type這個類生成的。type也是一個類,它的父類是什麼呢?
type.__base__
object
這裡有點繞,type類例項化了object,type類由繼承自object,這不矛盾。無論是type,還是object,它們即是物件,也是類,所以既擁有物件的特性,也擁有類的特性。剛說過,type掌管了物件的特性,object掌管了類的特性,所以兩者相互依存。我們 用一幅圖來說明,如下圖所示,虛線表示物件例項化生成關係,實線表示類的繼承關係。所有類都擁有物件的特資訊,所以都由type例項化生成,所有物件都擁有類的特性,所以都繼承自object。