Python类成员的困惑

首先,我来自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中编码?


慕少森
浏览 203回答 3
3回答

心有法竹

通常,您不会在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'

缥缈止盈

这将是这样的: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 = 10print c.myMember你有:# 10

慕尼黑的夜晚无繁华

在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。因此,如果我实例化上述类,它将打印:__init__ called!35还要注意,我可以通过该类访问该类的成员(您称其为“静态”):print Foo.member或通过实例:print Foo().__class__.member至于您将如何用python编写上述PHP……答案是您不会。最好这样写:class MyClass(object):    def __init__(self,mymember=None):        self.mymember = mymember确实没有充分的理由要有一个以设置私人成员为唯一目的的二传手。如果您希望用户能够重置mymember属性,那么惯用的方法是让他们可以直接访问它,而不是强迫他们调用函数来完成这项工作。mymember如果您发现确实需要该功能,则可以稍后再将其设为一个属性(如其他一些答案中所述)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python