【问题标题】:Static variable inheritance in PythonPython中的静态变量继承
【发布时间】:2011-03-29 09:03:17
【问题描述】:

我正在为一个项目为 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 让方法正确继承。谢谢!
  • 你为什么首先使用静态变量?这似乎不明智。这个active 属性是某种全局属性,在所有PanelToggle 实例之间共享吗?如果是这样,为什么它实际上不是全球性的?或者为什么不在一些更全局的共享对象中?
  • 我希望每个 panelToggle 子类都有自己的“活动”变量,无需创建实例即可访问。如果我正确理解“global”关键字的使用,我必须先在“invoke(..)”中插入一个“global active”行,然后才能像局部变量一样使用 active。这样做会产生一个错误,指出未定义全局名称“活动”。但是,我不确定我是否理解我的方法有什么问题。
  • 为什么是班级级别?显然,您希望每个子类都有一个变量。为什么是班级层面?这没什么意义。为什么这不是一个普通的实例变量?

标签: python inheritance syntax static blender


【解决方案1】:

使用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

【讨论】:

  • type(self) 与使用 self.__class__ 有何不同?
  • 目前没有。但有些功能可以稍后实现。你也可以做一些猴子补丁来输入函数。
  • 我使用的是 Python 3.8.5,但我注意到了一个区别:我无法从类的实例方法中修改 type(self).var。我必须使用 self.__class__.var 才能在实例方法中修改它。不知道为什么?
【解决方案2】:

您可以通过active所属的类访问它:

if panelToggle.active:
    # do something

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

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 做同样的事情。我希望它有自己的静态“活动”变量,继承自 panelToggle。我还想让“调用”方法在子类中工作(访问它自己的“活动”变量而不是它的父变量)
  • 编辑了我的帖子并在gist.github.com/522619中添加了示例代码,希望对您有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-28
  • 2020-10-18
  • 2011-04-24
  • 1970-01-01
  • 2016-09-10
  • 2017-01-10
  • 1970-01-01
相关资源
最近更新 更多