Python中的'self'用法 - 一个菜鸟在努力理解它
我有一个简单的套接字类:MySocketLib.py ..
import socket
class socklib():
def create_tcp_serversocket(self,port):
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind((socket.gethostname(), port))
serversocket.listen(5)
return serversocket
def send_msg(self, sock, msg, msglen):
... blah blah ...
def recv_msg(self, sock, msglen):
... blah blah ....
我的主文件是Server.py,内容如下:
import MySocketLib
class serverclass():
def __init__(self,port):
self.servsock = 0
self.port = port
def run(self):
self.servsock = self.create_tcp_serversocket(self.port)
(clientsock, address) = self.servsock.accept() # ERROR: 'SELF' not defined
... blah blah ...
#############################
### Main startup code
if __name__ == '__main__':
server = serverclass(2000) # server is on port 2000
server.run()
我一直遇到下面的错误:
File "D:\CodeLearn\Server.py", line 14, in serverclass
(clientsock, address) = self.servsock.accept()
NameError: name 'self' is not defined
我对“self”这个概念总是搞不清楚。有时候它看起来是必须的,有时候又不需要。为什么在这里我还需要定义'自我',它不是一个Python的关键字吗?
谢谢大家……问题确实是因为制表符和空格的设置。我使用的是Eclipse,在偏好设置中我把“编辑器”的选项设置为在缩进时使用空格。
3 个回答
你的缩进有问题,所以 __init__()
和 run()
被当成了顶层函数来理解——这样就没有自动的 self
参数了。你需要这样做:
class serverclass:
def __init__(self,port):
self.servsock = 0
self.port = port
def run(self):
self.servsock = self.create_tcp_serversocket(self.port)
(clientsock, address) = self.servsock.accept() # ERROR: 'SELF' not defined
... blah blah ...
这可能是缩进错误。
文件
"D:\CodeLearn\Server.py", line 14, in serverclass这意味着
(clientsock, address) = self.servsock.accept()
并不在 run 函数里面,而是在 serverclass 这个类里面。
在Python代码中不要使用制表符,记得把你的编辑器设置成只用空格。
self
不是Python的关键字,而是一种约定。它是你在使用的类的“实例”的常用名称。举个例子:
class X:
def __init__(self, v): self.v = v
a = X(1)
b = X(2)
print a.v, b.v
当这段代码运行时,Python会为两个 X
的实例分配内存,分别给 a
和 b
。如果没有像 self
这样的东西,你就得写:
a = X()
a.v = 1
b = X()
b.b = 2
print a.v, b.v
这样会出错,因为你写了 b.b
而不是 b.v
。而且,调用方法的方式会显得很糟糕:
class X:
def set(v): ???.v = v
你怎么说“访问在 X
的 __init__
中分配的 v
的引用”?
一种解决方法是把实例引用(指向为 X
分配的内存的指针)作为参数传递:
class X:
def set(a, v): a.v = v
a.set(a, 1) # Holy ugly!
每个人都会用不同的名称,这样就会违反DRY原则,搞得一团糟。所以Python的做法是:
class X:
def set(self, v): self.v = v
a.set(1) # while "set" runs, "self" == "a"
b.set(2) # while "set" runs, "self" == "b"
不过,我不明白为什么上面的代码会出错。显然 self
是定义过的,否则在你的 run()
方法的第一行就会出错。所以我猜是你在缩进时混用了空格和制表符,这让Python感到困惑,它看到的是:
def run(self):
self.servsock = self.create_tcp_serversocket(self.port)
(clientsock, address) = self.servsock.accept() # ERROR: 'SELF' not defined
然后它会在解析类定义时尝试执行 self.servsock.accept()
。那个时候,实例还不存在(类还没创建!),所以 self
也不可用。
总结:永远不要混用制表符和空格。