6

我不是一个完整的初学者,但对Python相当陌生。今天在做一个项目的时候,我有一个想法,想知道“ self ”的用法;关于我过去一段时间一直在阅读的内容,但我仍然无法弄清楚它是否总是必要的。我的问题仅涉及类的实例和实例参数/变量。这个问题与影响所有实例的类变量无关

示例

class C:
    def __init__(self, parent = None):
        super(C, self).__init__(parent)
        self.some_temp_var = AnotherClass()
        self.important_property = self.some_temp_var.bring_the_jewels()

ins_c = C()
print ins_c.important_property 

在上面的代码中,我在两个变量声明(some_temp_varimportant_property )之前都使用了self

稍后我需要从外部(创建实例的地方)访问 **important_property**,甚至可能对其进行修改。

但我不需要访问 AnotherClass() 的实例和/或指向它的变量(some_temp_var)。我只需要一次 it 类的实例,并且只需要执行一次它的方法 bring_the_jewels 来填充important_property的值。

在声明该变量之前我还应该使用 self 吗?

self.some_temp_var = ....
self.important_property = ....

或者可以是:

some_temp_var = ....
self.important_property = ....

感谢您的帮助。

附言。我做了很长的研究。由于缺乏我的英语和/或 CS 知识,我可能没有找到当前存在的重复项,但是我进行了搜索,并且进行了很多搜索。在将此问题称为“重复”或“不具建设性”之前,请通读。这是一个有明确答案的问题,非常重要,也很复杂。感谢您的理解。

4

3 回答 3

8

如果您不使用self.some_temp_var,那么您正在定义一个局部变量,该变量将在构造函数之后被垃圾收集。

所以是的,self如果你想定义一个应该与实例一起存在的实例属性,你需要。无论您需要它是公共的还是私有的,都是命名的问题。_为受保护或__私有添加前缀。

如果some_temp_var只是构造函数的临时对象,并且您再也不需要它,那么不,您不需要self. 它是关于持久性和成员属性的。您不需要self在单个方法中使用变量的纯粹事实。

考虑一下……如果some_temp_var您构建了一些巨大的数据结构以得出真正的结果值怎么办?您不想用来self存储临时变量,因为在您删除它或实例之前它不会释放内存。您希望在不再需要它时对其进行清理。

于 2012-12-30T20:34:04.367 回答
4

看起来你根本不需要这个变量:

class C:
    def __init__(self, parent=None):
        super(C, self).__init__(parent)
        self.important_property = AnotherClass().bring_the_jewels()

回应您的评论:

我需要把自己。如果它要在__init__.

不,你没有。然后使用常规变量,对象将在__init__退出后被垃圾收集。

class C:
    def __init__(self, parent = None):
        super(C, self).__init__(parent)
        some_temp_var = AnotherClass()
        self.important_property = some_temp_var.bring_the_jewels()
于 2012-12-30T20:34:11.250 回答
3

Python 并没有真正区分“公共”和“私有”变量。您使用'self.something = value'分配给self中的名称的任何内容都将成为该实例的实例变量。

Python 确实有两个相关的约定:

1) Python 字段或方法以下划线('_') 为前缀,告诉用户“这不是这个类之外的问题”。单个下划线是一种或多或少识别诸如 C# 之类的语言将什么称为“受保护”变量的常规方法:它是实现的内部变量,除了此类和派生类外,应单独保留。双下划线就像 C# 的“私有”变量:它是内部的,即使是派生类也应该单独使用,它不能被覆盖

class Example(object):
    def __init__(self)
       self._protected= "protected"
       self.__private = "private"
       self.public = "public"

class Derived(Example):
    pass

d = Derived()
print d._protected
>> protected
print d.__private
>> AttributeError: 'Derived' object has no attribute '__private'

严格来说,单下划线只是一种印刷约定。双下划线实际上会破坏类中的名称以防止继承。

2)如果AnotherClass实际上要挂起,并且如果操作AnotherClass实例会影响AnotherClass的状态,则您的示例可能是使用属性装饰器的情况。

class C:
    def __init__(self, parent = None):
        super(C, self).__init__(parent)
        self._private = AnotherClass()

    @property
    def public(self):
       return self._private.some_method_on_AnotherClass()

    @public.setter
    def set_pub(self, val)
       self._private.set_value_on_AnotherClass(val)
于 2012-12-30T20:46:43.333 回答