理解python的作用域规则 - 使用foo.var,self.var和var

时间:2017-02-06 08:34:58

标签: python

假设我有以下代码

<activity android:name=".activities.PaymentResultActivity"
        android:launchMode="singleTask"
        android:screenOrientation="portrait"
        android:theme="@style/AppThemeWhite"
        android:exported="true">
        <intent-filter android:autoVerify="true">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="myScheme" />
        </intent-filter>
    </activity>

我想知道class foo: str = "Hello World" def test(self): print(str) a = foo() a.test() 是否可以实际访问str变量?如果是这样,为什么输出只显示

print(str)

现在我已经阅读了一段时间的python,但我对这种情况感到困惑。我明白,如果我做了类似下面的事情

<type 'str'>

python最初会在实例中查找名为self.str 的变量,如果找不到变量,那么它会查找类变量,否则如果我想直接访问类变量,我会使用

str

所以我的问题是使用foo.str 访问哪个变量 print(str)与使用foo.str相同吗?

2 个答案:

答案 0 :(得分:2)

您很困惑,因为您选择了错误的变量名称。 str是内置字符串类型。您必须在类方法中使用self.前缀,并在它们之外使用实例前缀。

class foo:      
  s = "Hello World"
  def test(self):
    print(s)   # s not found
    print(self.s)  # OK!

请注意,您定义了一个变量,该变量在同一个类的实例之间共享(有时会产生奇怪的效果)。将该用法保留为常量。

要定义实例变量,请执行以下操作:

class foo:    
  def __init__(self):  
      self.s = "Hello World"

因此,您可以更改实例s上的A,而无需在实例B上更改它(对于字符串或整数等不可变项,它是不同的,但您不想这样做无论如何)

答案 1 :(得分:1)

没有自我:

foo.str是一个类变量,将在foo的所有实例之间共享,除非在实例中特别重写。

自我:

foo.str是一个实例变量,foo的每个实例都有自己的版本。

注意:

请注意,调用变量str并不是一个好习惯,因为它是python中的关键字