Python自我less

4

这样做可以按预期方式工作:

class d:
    def __init__(self,arg):
        self.a = arg
    def p(self):
        print "a= ",self.a

x = d(1)
y = d(2)
x.p()
y.p()

yielding

a=  1
a=  2

我尝试过在__init__中使用全局语句来消除"self"。
class d:
    def __init__(self,arg):
        global a
        a = arg
    def p(self):
        print "a= ",a

x = d(1)
y = d(2)
x.p()
y.p()

产生不良后果,不可取:
a=  2
a=  2

有没有一种方法可以不使用“self”来编写它?

4
你真正想要实现什么目标? - Michael Greene
试图使我的代码更易读。 - user717751
3
这会使代码 a) 不够符合 Python 风格并且 b) 无法正常运行。 - joce
3
当然,global a会导致所有实例共享变量 a,这基本上就是全局变量的定义。 - user395760
3个回答

6

"self"是Python语言的工作方式。因此,答案是:不需要!如果你想理发:你不必使用"self"。任何其他名称也可以。;-)


好的...所以我只需要习惯在我的代码中有很多"self"吗? - user717751
4
@mike:是的,句号,新段落。你差不多在问Python中避免预处理器的等价方法,就像在C和C++中一样。 - user395760
1
“很多”这个词取决于你的观点,但显然比其他语言中的单词更多。如果过多使用它们,可能暗示着您的代码存在问题。 - Achim
2
"显式优于隐式" - S.Lott
3
看到光明面,你就不会被诱惑在成员变量前添加“m_”来澄清方法内访问的命名空间 :) - ncoghlan

4

Python方法只是绑定到类或类实例的函数。唯一的区别是,方法(也称为绑定函数)期望将实例对象作为第一个参数。此外,当您从实例调用方法时,它会自动将实例作为第一个参数传递。因此,在方法中定义self时,您告诉它要使用的命名空间。

这样,当您指定self.a时,该方法知道您正在修改实例命名空间的一部分中的实例变量a

Python作用域由内而外工作,因此每个函数(或方法)都有自己的命名空间。如果您在方法p内部创建一个名为a的变量(这些名称很差),则它与self.a的变量是不同的。下面是使用您的代码的示例:

class d:
    def __init__(self,arg):
        self.a = arg
    def p(self):
        a = self.a - 99
        print "my a= ", a
        print "instance a= ",self.a


x = d(1)
y = d(2)
x.p()
y.p()

这将产生:

my a=  -98
instance a=  1
my a=  -97
instance a=  2

最后,你不必把第一个变量称为self。虽然你真的不应该这样做,但你可以给它取任何你想要的名字。按照惯例,在方法中定义和引用self,因此如果你在意其他人阅读你的代码而不想杀了你,那么请遵循惯例!
进一步阅读:

1
很好的解释,但一开始使用了误导性的术语:我们所谓的“绑定”方法已经有了实例(作为隐式第一个参数),而“非绑定”方法(在Python 2中,它有自己的类型;在Python 3中,它只是一个普通函数,但概念仍然存在)仍然需要实例(作为显式第一个参数)。 - user395760
这是我发布的第一个问题。我看到这个问题被评为-1,但我不确定原因。是因为这个问题不适合在SO上提出吗?还是表述不清楚?或者是因为我的回复格式不正确? - user717751
1
@delnan:你并不完全正确。如果你定义了一个以self作为第一个参数的裸函数,然后将其分配给类对象,那么该类的任何实例都将继承该函数作为绑定方法。在这种情况下,你所做的只是创建一个函数,将其附加到一个类上,它就成为了一个方法。但是,你是对的,实际上function的类型会变成instancemethod - jathanism
1
@mike:有人不喜欢你的问题并将其下投票。通常最好在原始问题中更加详细,而不是在评论中跟进。 :) - jathanism
1
这与我说的任何事情有冲突吗? - user395760
在我看來,對於初學者來說,關於神秘的「self」最好的解釋。+1 - Franz Forstmayr

0

当你移除self时,你最终只会有一个名为a的变量,它将被所有d对象共享,并且在整个执行环境中也是如此。因此,你不能仅仅为了这个原因而消除self。


好的,我现在明白了,global语句将变量提升到执行级别。 - user717751

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接