亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Python類成員的困惑

Python類成員的困惑

慕少森 2021-03-23 12:09:26
首先,我來自Java和PHP背景,現在正在學習python。因此,這似乎是一個愚蠢的問題,但這使我有些困惑。以php為例:class MyClass{   private $myMember;   public function __construct($myMember = null)   {       $this->myMember = $myMember;   }   public function setMyMember($myMember)   {       $this->myMember = $myMember;   }   public function getMyMember()   {       return $this->myMember;   }}這完全是101 OOP的教科書。一個具有單個私有成員以及一個getter和setter的類。但是,學習一些python似乎并不那么簡單。首先,構造函數不是真正的構造函數(但您可以在such ??上使用)其次,任何類級別的減速度都被視為靜態??。因此,python中的self.myMember實際上在實例上設置了與類級別myMember不同的變量嗎?最后,如果我的困惑是正確的-上面的相同示例將如何在python中編碼?
查看完整描述

3 回答

?
心有法竹

TA貢獻1866條經驗 獲得超5個贊

通常,您不會在Python中使用getter和setter;除非您需要轉換值,在設置或獲取過程中需要副作用,或者需要防止獲取或設置,否則,只需使用屬性即可:


class MyClass(object):

    def __init__(self, member):

        self.member = member

實例屬性與類屬性是分開的;將屬性設置為onself表示您正在操作實例,類(MyClass.member)上的屬性是類屬性,因此在實例之間共享。這是通過在查找屬性時將類用作備用方法來實現的。首先查詢實例,然后查詢實例的類,然后查詢該類的基類;設置self.member意味著MyClass.member在實例上不再可見任何對象。


從__init__技術上講,該方法實際上不是構造函數。被調用self時已經存在__init__。相反,它是一個初始化程序,您可以使用它設置第一個值。如果您需要一個實際的構造函數(實例工廠),則需要查找__new__靜態方法。請注意,在PHP中,它__construct也是一個初始化程序,而不是構造函數!


對于確實需要創建setter和getter的那些情況,請使用propertydecorator函數:


class MyClass(object):

    def __init__(self, member):

        self._member = member


    @property

    def member(self):

        return 'Hello {}!'.format(self._member)


    @member.setter

    def member(self, value):

        # Remove "Hello " and "!" from the start and end of any value being set.

        if value.startswith('Hello '):

            value = value.split(None, 1)[1]

        self._member = value.rstrip('!')

演示:


>>> m = MyClass('World')

>>> m.member

'Hello World!'

>>> m.member = 'Hello Planet Earth!'

>>> m.member

'Hello Planet Earth!'

>>> m._member

'Planet Earth'


查看完整回答
反對 回復 2021-03-26
?
縹緲止盈

TA貢獻2041條經驗 獲得超4個贊

這將是這樣的:


class MyClass(object):


    def __init__(self, myMember=None):

        self._myMember = myMember


    @property

    def myMember(self):

        return self._myMember


    @myMember.setter

    def myMember(self, value):

        self._myMember = value

演示:


c = MyClass()

c.myMember = 10

print c.myMember

你有:


# 10


查看完整回答
反對 回復 2021-03-26
?
慕尼黑的夜晚無繁華

TA貢獻1864條經驗 獲得超6個贊

在python中,類創建一個新的名稱空間。除非進行有趣的交易(例如元類),否則名稱空間中的內容就成為該類的屬性。


class Foo(object): #inherit from object in python2.x ... It's a good idea

     class_variable = 3

     __not_really_private_but_sort_of = 7

現在,我創建了一個具有2個屬性的類。第一個是“公共”。第二個是“ private”,因為它以雙下劃線為前綴,從而調用python的名稱修飾。在python中,很少使用。畢竟,我們都是這里的程序員:)。


當您調用一個類時,它調用__new__方法(構造函數),然后(如果__new__返回該類的實例)則調用初始化器(__init__)。在大多數情況下,您無需執行任何操作__new__-默認值__new__做得很好。由于__init__是常規方法,因此它將類的實例作為第一個參數-基本是this->從其他語言來填充指針的作用:


class Foo(object):

    member = 4

    other_member = 5

    def __init__(self):

        print "__init__ called!"

        self.member = 3

        print self.member

        print self.other_member

與其他語言相比,python有點奇怪的事實是,如果實例沒有成員,則python然后在類上然后在基類上查找成員(按方法解析順序搜索)。如果在任何地方都找不到該成員,則會引發一個AttributeError。因此,如果我實例化上述類,它將打?。?/p>


__init__ called!

3

5

還要注意,我可以通過該類訪問該類的成員(您稱其為“靜態”):


print Foo.member

或通過實例:


print Foo().__class__.member

至于您將如何用python編寫上述PHP……答案是您不會。最好這樣寫:


class MyClass(object):

    def __init__(self,mymember=None):

        self.mymember = mymember

確實沒有充分的理由要有一個以設置私人成員為唯一目的的二傳手。如果您希望用戶能夠重置mymember屬性,那么慣用的方法是讓他們可以直接訪問它,而不是強迫他們調用函數來完成這項工作。mymember如果您發現確實需要該功能,則可以稍后再將其設為一個屬性(如其他一些答案中所述)。


查看完整回答
反對 回復 2021-03-26
  • 3 回答
  • 0 關注
  • 227 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號