【问题标题】:How to access "self" inside the scope of a class?如何在类范围内访问“自我”?
【发布时间】:2014-04-05 14:36:46
【问题描述】:

我遇到了一个有趣的问题。

假设我们有一个类,并且在它的构造函数中我们将一个布尔值作为参数。如何根据实例的条件/布尔值在类中定义方法?例如:

class X():
    def __init__(self, x):
        self.x = x
    if self.x == true: # self is unreachable outside a method.
        def trueMethod():
            print "The true method was defined."
    if self.x == false: # self is unreachable outside a method.
        def falseMethod():
            print "The false method was defined."

【问题讨论】:

  • 你为什么要这样做?似乎只会让用户感到困惑。
  • self 在其他语言中类似于 this。它只能使用实例方法访问。
  • 在构造函数中定义你的方法。如果您希望它们成为方法,请给它们一个 self 参数。
  • @JayanthKoushik 我已经在 BrenBarn 的问题中解释了我为什么要这样做。

标签: python class scope instance self


【解决方案1】:

不,因为self 引用了一个实例,而在定义该类时还没有实例。

有一些方法可以实现类似的效果(例如在 __init__ 中基于每个实例重命名、添加或删除方法),但无论如何都没有真正的理由这样做。

【讨论】:

  • 在我正在开发的引擎中,我有一个 Grect 类(网格矩形),它可以用作背景或不用作背景(构造函数采用布尔值:isBackground)。如果布尔值为真,我定义“addBackground”方法,以便实例可以访问它。我不希望它不是背景的实例可以访问“addBackground”方法。
  • @EricsonWillians:有更好的解决方案。一种是为背景矩形创建一个子类并将方法放在那里。另一种方法是只给 Grect 类提供 addBackground 方法,但让它检查 self.isBackground 是否为真,如果不是则引发错误。
【解决方案2】:

您不能,但您可以定义不同名称的方法并在某些情况下公开它们。例如:

class X(object):
    def __init__(self, flag):
        if flag:
            self.method = self._method

    def _method(self):
        print "I'm a method!"

测试它:

>>> X(True).method()
I'm a method!
>>> X(False).method()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'X' object has no attribute 'method'

【讨论】:

    【解决方案3】:

    你不能这样做,但要动态定义一个方法,你可以使用types.MethodType

    from types import MethodType
    
    def trueMethod(self):
        print "The true method was defined."
    def falseMethod(self):
        print "The false method was defined."
    
    class X():
        def __init__(self, x):
            self.x = x
            if self.x:
                self.trueMethod = MethodType(trueMethod, self, X) 
            elif not self.x:
                self.falseMethod = MethodType(falseMethod, self, X)   
    

    【讨论】:

      【解决方案4】:

      您可以创建 dict 并基于价值访问功能,如

      def __init__(self, x):
          self.x = x
          self.my_dict = {True : lambda *a : print "True method", False: lambda *a: print "False method"}
      

      然后你就可以访问self.my_dict[self.x]了。

      【讨论】:

        猜你喜欢
        • 2017-09-24
        • 1970-01-01
        • 1970-01-01
        • 2012-10-13
        • 1970-01-01
        • 2017-02-09
        • 2016-06-23
        • 2012-02-23
        • 1970-01-01
        相关资源
        最近更新 更多