天天看點

python 類的成員變量_如何通路Python中的類的成員變量?

class Example(object):

def the_example(self):

itsProblem ="problem"

theExample = Example()

print(theExample.itsProblem)

如何通路類的變量?我試着加上這個定義:

def return_itsProblem(self):

return itsProblem

然而,這也失敗了。

标題編輯,關于類"靜态"變量的問題:stackoverflow.com/questions/707380/…

簡而言之,答案就在這裡

在您的示例中,itsProblem是一個局部變量。

必須使用self設定和擷取執行個體變量。您可以在__init__方法中設定它。那麼您的代碼将是:

class Example(object):

def __init__(self):

self.itsProblem ="problem"

theExample = Example()

print(theExample.itsProblem)

但是如果你想要一個真正的類變量,那麼直接使用類名:

class Example(object):

itsProblem ="problem"

theExample = Example()

print(theExample.itsProblem)

print (Example.itsProblem)

但是要注意這一點,因為theExample.itsProblem被自動設定為等于Example.itsProblem,但是根本不是相同的變量,可以獨立更改。

一些解釋

在Python中,變量可以動态建立。是以,您可以做以下工作:

class Example(object):

pass

Example.itsProblem ="problem"

e = Example()

e.itsSecondProblem ="problem"

print Example.itsProblem == e.itsSecondProblem

列印

True

是以,這正是您在前面的示例中所做的。

實際上,在Python中我們使用self作為this,但是它比這要多一點。self是任何對象方法的第一個參數,因為第一個參數總是對象引用。這是自動的,不管您是否将其稱為self。

這意味着你可以:

class Example(object):

def __init__(self):

self.itsProblem ="problem"

theExample = Example()

print(theExample.itsProblem)

或者:

class Example(object):

def __init__(my_super_self):

my_super_self.itsProblem ="problem"

theExample = Example()

print(theExample.itsProblem)

完全一樣。任何對象方法的第一個參數都是目前對象,作為約定,我們隻調用它self。你給這個對象添加一個變量,和你從外面做的一樣。

現在,關于類變量。

當你做的事:

class Example(object):

itsProblem ="problem"

theExample = Example()

print(theExample.itsProblem)

您将注意到,我們首先設定一個類變量,然後通路一個對象(執行個體)變量。我們從來沒有設定過這個對象變量但是它是有效的,這怎麼可能呢?

Python試圖首先擷取對象變量,但如果找不到,它會給你類變量。警告:類變量在執行個體之間共享,而對象變量不共享。

作為結論,永遠不要使用類變量将預設值設定為對象變量。為此使用__init__。

最後,您将了解到Python類是執行個體,是以是對象本身,這為了解上述内容提供了新的視角。當你意識到這一點的時候,回頭再讀一遍。

+ 1初始化。這就是它的作用。

你說:"他。它的問題被自動設定為等于執行個體。它的問題,但不是相同的變量,完全可以獨立地改變。"我相信你知道那裡發生了什麼,是以我建議換一種說法:"它是相同的變量,但它可以為每個對象獨立地重新綁定"。

是的,但是綁定是另一種程式設計語言的概念,比如Java或C(我懷疑OP是),它是完全未知的。然後我會解釋什麼是綁定,然後是後期綁定,最後是可變對象上引用的問題。時間太長了。我認為有時你必須在了解的祭壇上犧牲精确性。

還有一個@classmethod裝飾器(我認為可能是2.7+)值得研究。這裡有趣的讨論- stackoverflow.com/questions/12179271/…

名稱綁定:我認為給出錯誤的聲明是一個壞主意,無論級别如何。我建議進行這種輕微的編輯:但是要注意這一點,因為theExample.itsProblem被自動設定為等于Example.itsProblem,但是,從實際的角度來看*根本不是相同的變量,可以獨立地更改。*:實際上它一開始是相同的對象,但是如果不了解Python的名稱綁定,很容易意外地更改它

您聲明的是一個局部變量,而不是類變量。要設定執行個體變量(屬性),請使用

class Example(object):

def the_example(self):

self.itsProblem ="problem"  #

theExample = Example()

theExample.the_example()

print(theExample.itsProblem)

要設定類變量(也稱為靜态成員),請使用

class Example(object):

def the_example(self):

Example.itsProblem ="problem"

# or, type(self).itsProblem ="problem"

# depending what you want to do when the class is derived.

除非類變量在類級别聲明一次。你的方法會在每次瞬間重置它,這真的不是你想要的。有關顯式self背後的原理,請參見stackoverflow.com/questions/2709821/python-self-explained。

如果您有一個執行個體函數(即傳遞self的執行個體函數),您可以使用self使用self.__class__獲得對該類的引用

例如,在tornado下面的代碼中建立一個執行個體來處理get請求,但是我們可以獲得get_handler類并使用它來儲存riak客戶機,是以我們不需要為每個請求建立一個執行個體。

import tornado.web

import riak

class get_handler(tornado.web.requestHandler):

riak_client = None

def post(self):

cls = self.__class__

if cls.riak_client is None:

cls.riak_client = riak.RiakClient(pb_port=8087, protocol='pbc')

# Additional code to send response to the request ...

實作return語句,如下面的示例所示!你應該表現得很好。我希望它能幫助一些人…

class Example(object):

def the_example(self):

itsProblem ="problem"

return itsProblem

theExample = Example()

print theExample.the_example()

您應該修複代碼縮進。這個問題也有更好的答案,你的答案是這些答案的基本變體,而不是替代的解決方案……