Python中静态变量的继承

14

我正在为一个项目编写Blender的Python脚本,但是我对这种语言还很陌生。有一件事让我困惑,那就是静态变量的使用。下面是我目前正在处理的代码:

class panelToggle(bpy.types.Operator):
    active = False

    def invoke(self, context, event):
        self.active = not self.active
        return{'FINISHED'}

class OBJECT_OT_openConstraintPanel(panelToggle):
    bl_label = "openConstraintPanel"
    bl_idname = "openConstraintPanel"

这个想法是第二个类应该从第一个类继承active变量和invoke方法,以便调用OBJECT_OT_openConstraintPanel.invoke()可以改变OBJECT_OT_openConstraintPanel.active的值。然而,如上所示使用self是行不通的,而使用panelToggle也不行。你有什么建议吗?


好的,看起来我可以使用self.class.active或type(self).active来让方法正确继承。谢谢! - gibberish
你为什么要使用静态变量?这似乎不合理。这个 active 属性是一种全局共享于所有 PanelToggle 实例之间的属性吗?如果是,为什么它不是真正的全局变量呢?或者为什么它不是某个更全局的共享对象的属性呢? - S.Lott
我希望每个panelToggle子类都有自己的“active”变量,可以在不创建实例的情况下访问。如果我正确理解了“global”关键字的用法,在“invoke(..)”中使用active就像使用本地变量一样,我需要先插入一个“global active”行。 但是这样做会出现错误,说全局名称“active”未定义。 然而,我不确定我的方法有什么问题。 - gibberish
为什么是类级别的?显然,您希望每个子类都有一个变量。为什么要在类级别上?这没有太多意义。为什么不是普通实例变量? - S.Lott
2个回答

22

使用 type(self) 访问类属性

>>> class A(object):
 var  = 2
 def write(self):
   print(type(self).var)
>>> class B(A):
 pass
>>> B().write()
2
>>> B.var = 3
>>> B().write()
3
>>> A().write()
2

更新

对于一个classmethod来说,更容易,更自然。

class A(object):
     var  = 2
     @classmethod
     def write(cls):
       print(cls.var)

staticmethod 不应该依赖于实例类型,因此此处可能使用这种形式的分派。


4
type(self)self.__class__ 是否有任何区别? - jorelli
3
目前还不行,但一些功能以后可以实现。此外,您可以对type函数进行一些“猴子补丁”。 - Odomontois
我正在使用Python 3.8.5,我注意到一个区别:我无法在类的实例方法内部修改type(self).var。我必须使用self.class.var才能够在实例方法内部进行修改。不确定为什么? - mattyb
如果write是一个静态方法,有没有一种方法可以实现这个? - ekkis
@ekkis稍微更新了一个答案。 - Odomontois

4
您可以通过所属类别访问active
if panelToggle.active:
    # do something

如果您想从方法中访问变量,您可以这样写:

def am_i_active(self):
    """ This method will access the right *class* variable by
        looking at its own class type first.
    """
    if self.__class__.active:
        print 'Yes, sir!'
    else:
        print 'Nope.'

这里有一个可操作的示例: http://gist.github.com/522619


self变量(按照惯例命名为self)是当前类的实例,在不显式接受但隐式传递。

class A(object):

    answer = 42

    def add(self, a, b):
        """ ``self`` is received explicitely. """
        return A.answer + a + b

a = A()

print a.add(1, 2) # ``The instance -- ``a`` -- is passed implicitely.``
# => 45

print a.answer 
# => print 42

是的,但我希望能够使用OBJECT_OT_openConstraintPanel实现相同的功能。我希望它拥有自己的静态“active”变量,从panelToggle继承而来。我还想让子类中的“invoke”方法工作(访问自己的“active”变量而不是父类的变量)。 - gibberish
编辑了我的帖子,并在http://gist.github.com/522619中添加了示例代码,希望对你有所帮助。 - miku

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接