Python类成员混淆

2024-09-27 00:22:49 发布

您现在位置: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哦。一个只有一个私有成员和一个getter和setter的类。在

然而,学习一些python并不是那么简单。在

首先,构造函数不是真正的构造函数(但您可以在这样的地方使用)在

第二,任何类级减速都被视为静态的??所以self.myMember在python中,实际上在实例上设置了一个与类级别myMember不同的变量?在

最后,如果我的误解是正确的,那么上面的同一个例子是如何用python编写的?在


Tags: returnmyclassfunctionjavaprivatepublicthisconstruct
3条回答

通常,在Python中不使用getter和setters;除非需要转换值,在设置或获取期间需要副作用,或者需要阻止获取或设置,否则只需使用属性:

class MyClass(object):
    def __init__(self, member):
        self.member = member

实例属性与类属性是分开的;在self上设置属性意味着您正在操作实例,类(MyClass.member)上的属性是类属性,因此在实例之间共享。这是通过在查找属性时使用类作为后备来实现的;首先查询实例,然后查询实例的类,然后查询类的基类;设置self.member意味着任何{}在实例上不再可见。在

从技术上讲,__init__方法实际上不是构造函数。^调用__init__时,{}已存在。它是一个初始值设定项,你可以用它来设置第一个值。如果需要实际的构造函数(实例工厂),则需要查找^{} static method。注意,在PHP中,__construct也是一个初始值设定项,而不是构造函数!在

对于那些需要创建setter和getter的情况,请使用^{} decorator function

^{pr2}$

演示:

>>> m = MyClass('World')
>>> m.member
'Hello World!'
>>> m.member = 'Hello Planet Earth!'
>>> m.member
'Hello Planet Earth!'
>>> m._member
'Planet Earth'

在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的名称mangling。在python中,这是很少使用的。毕竟,我们都是同意的程序员:)。在

当您调用一个时,它将调用__new__方法(构造函数),然后(如果__new__返回该类的实例),它将调用初始值设定项__init__)。大多数时候,您不需要对__new__做任何事情——默认的__new__做得很好。由于__init__是一个常规方法,因此它接收类的实例作为第一个参数——基本上填充来自其他语言的this->指针的角色:

^{pr2}$

与其他语言相比,python有一点奇怪:如果一个实例没有成员,python会在上查找成员,然后在基类上查找(按方法解析顺序搜索)。如果它在任何地方都找不到成员,那么它将引发一个AttributeError。因此,如果我实例化上面的类,它将打印:

__init__ called!
3
5

还请注意,我可以通过类访问类(如您所说的static)成员:

print Foo.member

或者通过一个实例:

print Foo().__class__.member

至于如何用python编写上面的PHP。。。答案是你不会的。最好这样写:

class MyClass(object):
    def __init__(self,mymember=None):
        self.mymember = mymember

真的没有什么好的理由让一个设定者的唯一目的是设置一个私人成员。如果希望用户能够重置mymember属性,那么惯用的方法是让用户直接访问该属性,而不是强制用户调用函数来执行该操作。如果您发现您确实需要mymember功能,您可以在以后将mymember变成属性(如其他一些答案中所述)。在

应该是这样的:

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

演示:

^{pr2}$

你有:

# 10

相关问题 更多 >

    热门问题