python:一切皆對象

 

學過java語言的童鞋都知道,java是一門面向對象語言,其基本思想就是一切皆對象。Python也是一樣的,甚至Python將面向對象思想貫徹地更加徹底,因為在Python中,class本身是一個對象,class實例化出來的實例也是對象,方法函數是一個對象,甚至程式碼模組都是一個對象,這是java不曾擁有的。

 

對象的一個重要特性就是可以被賦值給其他變數,我們說方法、函數、類都是對象,那麼,當然也具有這一特性:

In [1]:
def say(name='張三'):
    print('I am %s' % name)
In [2]:
func = say
func('李四')
 
I am 李四
 

甚至函數內部還可以將函數作為返回值,注意這一特性非常重要,因為這是Python裝飾器的基礎:

In [20]:
def func(flag):
    if flag:
        def func1():
            return 1
    else:
        def func1():
            return 2
    return func1
In [22]:
f = func(flag=True)
f()
Out[22]:
1
 

再來看看類的賦值:

In [17]:
class Student:
    def __init__(self, name='張三'):
        self.name = name
        print('I am %s' % name)
In [4]:
my_class = Student
In [5]:
my_class('李四')
 
I am 李四
Out[5]:
<__main__.Student at 0x7ff029457910>
 

我們還可以繼續講類和函數放進一個list中:

In [6]:
lst = []
lst.append(func)
lst.append(Student)
In [7]:
lst[0]('王五')
 
I am 王五
In [8]:
lst[1]('王五')
 
I am 王五
Out[8]:
<__main__.Student at 0x7ff0294524d0>
 

可見,類和函數方法都是對象。

 

2 class type object的關係

 

在上文中我們說過,Python中一切皆對象,class也不例外,而class就是用來生成object的對象,那麼,既然class也是一個對象,它又是誰生成的呢?沒錯,就是type,可以這麼認為,type就是用來生成class(類)的一種對象。

 

我們知道,Python中有一個type()方法,可以查看傳遞的實例是有哪個類生成的:

In [24]:
class Person:
    pass
In [26]:
p = Person()
type(p)
Out[26]:
__main__.Person
 

可以看到,type(p)指向的是一個Person類。那麼,如果我們對Person類使用type()呢?

In [27]:
type(Person)
Out[27]:
type
 

返回的是一個type,那麼,我們可以認為,type是生成Person類的類。type這個類對象本身又是由誰生成的呢?

In [29]:
type(type)
Out[29]:
type
 

可知,type對象也是由type本身生成的。所以,type是最頂層的類,一切類對象都是由type生成。

 

對象和類是兩種不同的概念,對象是一個具體的概念,是類這個模板生成出來的。在Python中,類既擁有作為一個對象的特性,也有用對象的特性,我們可以認為,Python類中所擁有的對象的特性是由type所生成、賦予的。那麼,Python類所擁有的作為一個類的特性是誰賦予的呢?

那就是object。

在java中,任何一個沒有明確指明繼承關係的類,都繼承object類,在Python中也不例外:

In [30]:
class Person:
    pass
 

調用類的base屬性可以查看父類:

In [31]:
Person.__base__
Out[31]:
object
 

在定義Person類時,我們沒有指明繼承關係,所以,默認就繼承自object類。除了自定義的類外,Python的內置類型也一樣繼承自object:

In [33]:
int.__base__
Out[33]:
object
In [34]:
str.__base__
Out[34]:
object
 

object的父類會是誰?

In [38]:
print(object.__base__)
 
None
 

可知,object沒有父類。

 

繼續,object類是不是對象呢?肯定是,因為Python無處不對象,那麼,object是哪個類實例化生成的呢?

In [35]:
type(object)
Out[35]:
type
 

可見,object是由type這個類生成的。type也是一個類,它的父類是什麼呢?

In [36]:
type.__base__
Out[36]:
object
 

這裡有點繞,type類實例化了object,type類由繼承自object,這不矛盾。無論是type,還是object,它們即是對象,也是類,所以既擁有對象的特性,也擁有類的特性。剛說過,type掌管了對象的特性,object掌管了類的特性,所以兩者相互依存。我們 用一幅圖來說明,如下圖所示,虛線表示對象實例化生成關係,實線表示類的繼承關係。所有類都擁有對象的特資訊,所以都由type實例化生成,所有對象都擁有類的特性,所以都繼承自object。

 

Tags: