我是Python的新手,具有Java背景," self"在功能混淆了我。我理解第一个论点" self"表示对象本身,但我不明白Python如何使这个工作。我也知道我可以使用"这个"或"那"或者" somethingElse",Python仍然理解我的意思是使用该对象。
我从reddit post复制了一些代码:
class A():
def __init__(self):
self.value = ""
def b(this):
this.value = "b"
def c(that):
that.value = "c"
a = A()
print(a.value)
a.b()
print(a.value)
>>>"b"
a.c()
print(a.value)
>>>"c"
python如何知道我不是故意在第一个参数中使用对象?例如,我稍微修改了上面的代码:
class A():
def __init__(self):
self.value = ""
def b(this):
this.value = "b"
def c(that):
that.value = "c"
def somethingElse(someObjectIWantToPass):
someObjectIWantToPass.value = "still referring A.value"
class B():
def __init__(self):
self.value = ""
a = A()
print(a.value)
a.b()
print(a.value)
a.c()
print(a.value)
a.somethingElse()
print(a.value)
b = B()
a.somethingElse(b)
print (b.value)
它破了:
b
c
still referring A.value
Traceback (most recent call last):
File "D:/Documents/test.py", line 32, in <module>
a.somethingElse(b)
TypeError: somethingElse() takes 1 positional argument but 2 were given
答案 0 :(得分:6)
方法的第一个参数是始终 1 其实例。调用它self
在Python中是惯用的,但该名称是严格约定的。
class A():
def some_method(me): # not called `self`
print(str(id(me))
a = A()
a.some_method()
print(id(a))
如果你试图传递另一个任意对象,它必须是第二个参数。
class B():
def another_method(self, other):
print(id(other))
b = B()
b.another_method(a)
print(id(b)) # different!
print(id(a)) # the same.
1 实际上并非总是如此。 @classmethod
装饰方法使用cls
作为第一个参数,@ staticmethod`修饰方法默认情况下没有传递给第一个参数。
class C():
@classmethod
def some_classmethod(cls, other, arguments):
# first argument is not the instance, but
# the class C itself.
@staticmethod
def something_related(other, arguments):
# the first argument gets neither the instance
# nor the class.
答案 1 :(得分:1)
你太专注于语法糖了。只是意识到python中非静态成员函数中的第一个参数是对当前对象的引用。无论您是要将其称为this
,that
,foobar
,poop
,都无关紧要。成员函数的第一个参数被认为是对调用该方法的对象的引用。
self
的使用只是每个人都理解它的通用方式以及Python
推荐的方式 - 如果可能的话,这是一种约定。
**kwargs
和*args
也是如此。这些只是渗透到Python生态系统中的惯例,每个人都只是以这种方式使用它,但这并不意味着你不能给它们一个不同的名称。
你的上一个例子破了,因为你正在调用的函数(A.something
)不带任何参数。如果您理解我之前所说的非静态成员函数中的第一个参数是对调用该方法的对象的引用,那么这将是有意义的。