如何从Python中的方法访问函数

如何从Python中的方法访问函数,python,oop,sockets,tkinter,Python,Oop,Sockets,Tkinter,问题 在同一个类中,如何从方法中访问函数 背景 你好,世界!我目前正在使用Tkinter开发一个GUI IM程序。要通过套接字发送消息,我需要从方法访问函数。我的self.network方法有一个名为send\u message()的函数,我想访问该函数 代码 要访问它,我尝试使用以下代码: def messageFun(self): //Other widgets are here// self.send = Button (self.messageFrame, text

问题

在同一个类中,如何从方法中访问函数

背景

你好,世界!我目前正在使用Tkinter开发一个GUI IM程序。要通过套接字发送消息,我需要从方法访问函数。我的
self.network
方法有一个名为
send\u 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
回溯(最近一次呼叫最后一次):
文件“D:\Python Programs\Sockets\First Project\IM Project\Server GUI InDev.py”,第178行,在
app=应用程序(根)
文件“D:\Python Programs\Sockets\First Project\IM Project\Server GUI InDev.py”,第73行,在\uuu init中__
self.messageFun()
messageFun中的文件“D:\Python Programs\Sockets\First Project\IM Project\Server GUI InDev.py”,第156行
command=self.network(发送消息())
NameError:未定义全局名称“发送消息”

如果需要在
网络
之外访问
发送消息
,则应在
网络
之外定义

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
当前未返回任何内容,则可以在
network
内部定义
send_message
,并在末尾返回它

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)
若网络已经有一个返回值,那个么你们可以把网络的局部变量放在类的作用域中,这样
send\u 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\u message())
是一种奇怪的语法,用于尝试触发函数
send\u 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())
在第二段代码中,我将
pass
放在
network()
函数中,因为我不知道实际函数的内容,但您将用此内容代替此
pass

我将这些方法放在一个类
NENE
中,以展示它是如何工作的。因为
send\u message()
必须是与
network()
是方法的实例相同的方法。
然后,在每次创建新实例时,
send\u message()
也成为
network()
方法的一个属性。
因此,
send_message()
是实例及其方法的一个属性;但这并不重要,只是它实现了您的目标:
send\u message()
现在是
network()
的一个属性,可以通过
network
属性调用它,它知道它的工作实例是什么


请原谅我的英语不好

问题是,当我尝试这样做时,套接字没有定义。难道没有更简单的方法吗?我可以创建一个GUI类继承自的网络类吗?
s
socket?定义在哪里?
s
确实是套接字。有没有什么方法可以让我直接从一个方法中访问一个函数。除此之外,我可以创建两个类吗?一个是
GUI
类,另一个是
Network
类,当需要发送内容时,它们可以互相访问?您好。我已经更新了我的答案。然而,我认为您遇到了XY问题,因为在我看来,您试图以一种不清楚的方式做一些事情,我看到您的用户页面上,您说“我刚刚开始编程”。为什么你认为在方法中加入一个函数会给你发送消息的方式?我认为你们班的概念不好。但是我们看不到你们的类,只看到你们向我们提出的Y问题XY问题()。在()中,我们读到“X-Y问题,有时也被称为X-Y问题,是一种精神障碍,它会导致大量时间和精力的浪费,无论是请求帮助的人还是提供帮助的人。”正如@eyquem在他的回答中提到和解释的那样,方法中的函数是错误的做法。我不知道Python为什么允许这样做。只提取该函数并将其作为方法编写,然后在类中的任何位置访问它,这有什么错呢?
\uu dict\uu
是什么意思?另外,您所说的
实例
是什么意思?名为
的属性是表示对象名称空间的字典,也就是说,对象的所有属性与这些属性的标识符(=名称)之间的映射。Python大量使用字典来表示名称空间。理解Python需要理解这一方面。指令
self.network.\uu dict\uuuuuu['send']=send\u message
网络的命名空间中创建一个新属性:对象send\u message被分配给标识符
send
,该标识符是
网络的命名空间键的一部分。@xxmbaanexx
实例
只是一个名称,一个标识符。之所以这样命名,是因为必须作为参数传递给函数
send_message()
的对象实际上是类的实例(你不知道这个类是什么,然后我在第二段代码中称它为NENE)
send_message()
不是第一个代码中的方法,它不在类中,这就是为什么我有权命名参数
instance
,而不是通用的
self
名称。