如何在Python中从方法访问函数
问题
在同一个类里,怎么在一个方法中访问另一个函数呢?
背景
你好,世界!我现在正在用Tkinter做一个图形界面的即时通讯程序。为了通过网络发送消息,我需要在方法中访问一些函数。我的 self.network
方法里有一个叫 send_message()
的函数,我想要访问它。
代码
为了访问这个函数,我尝试了以下代码:
def messageFun(self):
//Other widgets are here//
self.send = Button (self.messageFrame, text = "Send",
command = self.network(send_message()))
self.send.grid(row = 1, column = 1, sticky = S)
我的 self.network
方法和 send_message
函数如下:
def network(self):
def send_message():
#Send some data to the remote server
message = self.message.get("0.0",END)
try:
#set the whole string
s.sendall(message)
except socket.error:
#Send Failed
print "Send failed"
sys.exit()
尽管我努力调试代码,但总是收到这个消息:
Traceback (most recent call last):
File "D:\Python Programs\Sockets\First Project\IM Project\Server GUI InDev.py", line 178, in <module>
app = Application(root)
File "D:\Python Programs\Sockets\First Project\IM Project\Server GUI InDev.py", line 73, in __init__
self.messageFun()
File "D:\Python Programs\Sockets\First Project\IM Project\Server GUI InDev.py", line 156, in messageFun
command = self.network(send_message()))
NameError: global name 'send_message' is not defined
2 个回答
如果你想在 network
之外使用 send_message
,那么就应该把它放在 network
之外来定义。
def send_message(self):
#Send some data to the remote server
message = self.message.get("0.0",END)
try:
#set the whole string
s.sendall(message)
except socket.error:
#Send Failed
print "Send failed"
sys.exit()
def network(self):
#do network stuff...
def messageFun(self):
//Other widgets are here//
self.send = Button (self.messageFrame, text = "Send",
command = self.send_message)
self.send.grid(row = 1, column = 1, sticky = S)
如果 send_message
需要用到 network
内部的变量,而 network
现在又没有返回任何东西,那么你可以把 send_message
放在 network
里面定义,并在最后返回它。
def network(self):
#create the socket needed for send_message
s = Socket()
def send_message():
#Send some data to the remote server
message = self.message.get("0.0",END)
try:
#set the whole string
s.sendall(message)
except socket.error:
#Send Failed
print "Send failed"
sys.exit()
#do other network stuff...
return send_message
def messageFun(self):
//Other widgets are here//
self.send = Button (self.messageFrame, text = "Send",
command = self.network()
self.send.grid(row = 1, column = 1, sticky = S)
如果 network
已经有返回值了,那么你可以把 network
内部的变量放到类的范围内,这样 send_message
就能访问到这些变量了。
def send_message(self):
#Send some data to the remote server
message = self.message.get("0.0",END)
try:
#set the whole string
self.s.sendall(message)
except socket.error:
#Send Failed
print "Send failed"
sys.exit()
def network(self):
#create the socket needed for send_message
self.s = Socket()
#do other network stuff
def messageFun(self):
//Other widgets are here//
self.send = Button (self.messageFrame, text = "Send",
command = self.send_message
self.send.grid(row = 1, column = 1, sticky = S)
network(send_message())
这个写法看起来有点奇怪,因为它试图去调用 send_message()
这个函数。
我建议可以用下面这种方式:
def send_message(instance):
#Send some data to the remote server
message = instance.message.get("0.0",END)
try:
#set the whole string
s.sendall(message)
except socket.error:
#Send Failed
print "Send failed"
sys.exit()
def network(self,what,send_message=send_message):
if what =='send message":
send_message(self)
self.send = Button (self.messageFrame, text = "Send",
command = self.network("send message"))
或者用这种方式:
class NENE:
def __init__(self):
self.network.__dict__['send'] = send_message
def send_message(self):
#Send some data to the remote server
message = self.message.get("0.0",END)
try:
#set the whole string
s.sendall(message)
except socket.error:
#Send Failed
print "Send failed"
sys.exit()
def network(self):
pass
self.send = Button (self.messageFrame, text = "Send",
command = self.network.send_message())
在第二段代码中,我在 network()
函数里放了一个 pass
,因为我不知道你真正的函数内容是什么,但你可以把你的内容放在这个 pass
的位置。
我把这些方法放在一个叫 NENE
的类里,目的是为了展示它是怎么工作的。因为 send_message()
必须是和 network()
方法属于同一个实例的方法。
这样,每次创建一个新实例的时候,send_message()
也会成为 network()
方法的一个属性。
所以,send_message()
既是这个实例的一个属性,也是它的一个方法的属性;不过这并不重要,重要的是它达到了你的目的:send_message()
现在是 network()
的一个属性,可以通过 network
属性来调用,并且它知道自己是为哪个实例工作的。
抱歉我的英语不好。