首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在类中的其他位置访问这些函数和变量(Python)

在类中的其他位置访问这些函数和变量(Python)
EN

Stack Overflow用户
提问于 2018-07-18 06:35:26
回答 1查看 52关注 0票数 -1

我遵循来自http://sthurlow.com/python/lesson08/的教程:

我不明白以下几点:

在第一层缩进上创建的任何函数或变量(即,在我们放置类形状的位置右侧开始一个制表符的代码行将自动放入self中。要在类中的其他位置访问这些函数和变量,它们的名称必须以self和句号开头(例如self.variable_name)。

以下是所用示例的一部分:

代码语言:javascript
复制
#An example of a class
class Shape:
    def __init__(self,x,y):
        self.x = x
        self.y = y
    description = "This shape has not been described yet"
    author = "Nobody has claimed to make this shape yet"
    def area(self):
        return self.x * self.y
    def perimeter(self):
        return 2 * self.x + 2 * self.y
    def describe(self,text):
        self.description = text

我理解self.x如何影响代码的__ init __部分,但不是函数,因为它们似乎遵循不同的规则(例如,我不能从函数内部访问变量)……换句话说,我试图弄清楚self.x在函数中做了什么。如果我只把x放在函数中,它会做什么?如果我把x放在__ int __中,它只‘活’在__ int中,并且不能在创建对象时被调用。如果我把self.x放在__int中,当我创建一个对象时就可以调用它。我想知道self.x和x在函数中的区别,因为我找不出测试它的代码

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-18 07:04:55

我理解self.x如何影响__ init __部分代码,但不是函数,因为它们似乎遵循不同的规则(例如,我不能从函数内部访问变量)……

不,他们真的不遵守不同的规则。__init__只是一个在class定义中定义的函数,与area完全一样。

它们都将self作为显式参数,如果要访问或设置实例属性(如x )或调用实例方法(如describe ),则必须使用该self

唯一不同的是它们的名称:

  • area是可以直接调用的东西。当您编写my_shape.area()时,它会调用area函数,并将my_shape作为Python的值自动调用。当您编写my_shape = Shape(2, 3)时,Python将构造一个新的Shape对象,然后调用__init__函数,将该新对象作为self传递(将23作为x和Python传递

换句话说,我试图弄清楚

在函数中做了什么。如果我只把x放在函数中,它会做什么?

普通老式x是一个局部变量,如果没有,就是一个全局变量。因此,在__init__中,有一个名为x的参数,它就是那个x (例如,在Shape(2, 3)示例中它是2 )。在area中,没有任何名为x的局部变量,它将是一个全局变量。但是您可能也没有名为x的全局变量,因此它将引发一个NameError

另一方面,self.x是任何selfx属性。如上所述,self__init__中新创建的Shape实例,以及您在area中调用area的任何Shape实例。

如果我把x放在__ int中,它只‘活’在__ int中,不能在我创建对象时被调用。

是的,如果您在__init__中定义了一个名为x的东西,那么它是一个局部变量,所以它只存在于__init__中。这适用于任何函数-不仅仅是__init__,甚至不只是类中定义的方法;这就是局部变量的含义。一旦函数结束,这些变量就消失了,再也没有人能访问它们。(如果涉及闭包,情况就不是这样了,但是它们不在这里,所以忽略它。)

我不知道您所说的“调用”是什么意思,因为您通常不会调用不是函数/方法/类的值,我也不知道您所说的“当我创建一个对象时”是什么意思,因为当您创建一个对象时正是__init__被调用的时候。

如果我把self.x放在__int中,当我创建一个对象时就可以调用它。

您在__init__中分配给self.x的任何内容都将存储为该self实例的一部分。因此,拥有该实例的任何人都可以再次访问该实例。例如,在area中,您可以作为self.x访问它。或者,从顶级代码中,您可以作为my_shape.x访问它。

同样,这里关于__init__没有什么特别之处;您可以在另一个方法中做同样的事情-就像describe方法一样。您甚至可以从对象外部执行此操作。

例如:

代码语言:javascript
复制
>>> my_shape = Shape(2, 3)
>>> my_shape.x
2
>>> my_shape.area()
6
>>> my_shape.x = 4
>>> my_shape.area()
12

再说一次,我不知道你说的“被调用”或者“当我做一个对象时”是什么意思。

我想知道self.x和x在函数中的区别,因为我找不出测试它的代码

尝试添加此方法:

代码语言:javascript
复制
def play_with_x(self):
    x = 10
    print(x)
    print(self.x)
    x = 20
    print(x)
    print(self.x)
    self.x = 30
    print(x)
    print(self.x)

然后试试这个:

代码语言:javascript
复制
>>> x = 0
>>> my_shape = Shape(2, 3)
>>> my_shape.play_with_x()

您将看到它可以更改xself.x。它们彼此完全独立,但在一个函数中看起来大部分行为都是相同的。但现在:

代码语言:javascript
复制
>>> x
0
>>> my_shape.x
30

x = 20没有对全局变量x做任何操作。但是那个self.x = 30确实永久地改变了self,它和my_shape是同一个对象,所以my_shape.x现在30岁了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51391079

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档