简体   繁体   English

在python中引用来自其他线程/类的变量?

[英]Referencing a variable from a different thread/class in python?

What I'm trying to achieve is quite simple. 我想要实现的目标非常简单。

So basically, I have a thread that loops continuously, grabbing data from the same url and updating a variable called "data", with text each time. 因此,基本上,我有一个连续循环的线程,从相同的url获取数据并更新一个名为“ data”的变量,每次都带有文本。 The variable is stored locally within the class. 变量存储在本地类中。

Then I have a second class which is the mainframe. 然后我有第二类,即大型机。 It should display the latest data, which is determined by whatever the variable in the first class is set to. 它应显示最新数据,该数据取决于将第一类中的变量设置为什么。

The problem is that I cannot find a way to reference that variable from the other class/thread. 问题是我找不到从其他类/线程引用该变量的方法。

The name of the variable that I am setting, and trying to reference is "data". 我正在设置并尝试引用的变量的名称为“数据”。

Here is the source code: 这是源代码:

#!/Library/Frameworks/Python.framework/Versions/3.5/bin/python3
# -*- coding: utf-8 -*-

from tkinter import *
import time
import urllib.request
from bs4 import BeautifulSoup
import threading
from queue import Queue

class httpReq(threading.Thread):

    def run(self):

        i = 0
        while 1<5:
            url = "https://twitter.com/realDonaldTrump"
            page = urllib.request.urlopen(url)
            soup = BeautifulSoup(page, "html.parser")
            self.data = data = soup.title.text
            print(x)

x = httpReq()
x.start()

class Example(Frame, httpReq):

    def __init__(self, parent):
        Frame.__init__(self, parent)

        self.parent = parent
        self.initUI()

    def initUI(self):

        self.parent.title("IT Support App")
        self.pack(fill=BOTH, expand=True)

        frame1 = Frame(self)
        frame1.pack(fill=X)

        lbl1 = Label(frame1, text="Primary Video Stream", width= 20)
        lbl1.pack(side=LEFT, padx=5, pady=5)


        lbl6 = Label(frame1, text= x.data)
        lbl6.pack(fill=X, padx=5, expand=True)

        frame2 = Frame(self)
        frame2.pack(fill=BOTH, expand=True)

        lbl2 = Label(frame2, text="Primary Audio Stream", width=20)
        lbl2.pack(side=LEFT, padx=5, pady=5)

        entry2 = Entry(frame2)
        entry2.pack(fill=X, padx=5, expand=True)

        frame3 = Frame(self)
        frame3.pack(fill=BOTH, expand=True)

        lbl3 = Label(frame3, text="Backup Video Stream", width=20)
        lbl3.pack(side=LEFT, padx=5, pady=5)

        entry3 = Entry(frame3)
        entry3.pack(fill=X, pady=5, padx=5, expand=True)

        frame4 = Frame(self)
        frame4.pack(fill=BOTH, expand=True)

        lbl4 = Label(frame4, text="Backup Audio Stream", width=20)
        lbl4.pack(side=LEFT, padx=5, pady=5)

        entry4 = Entry(frame4)
        entry4.pack(fill=X, pady=5, padx=5, expand=True)

        frame5 = Frame(self)
        frame5.pack(fill=X)

        lbl5 = Label(frame5, text="IPTV", width=20)
        lbl5.pack(side=LEFT, padx=5, pady=5)

        entry5 = Entry(frame5)
        entry5.pack(fill=X, pady=5, padx=5, expand=True)

def main():

    root = Tk()
    root.geometry("1920x1080")
    app = Example(root)
    root.mainloop()


if __name__ == '__main__':
    main()

Try to declare the data variable outside of the while loop and the run method. 尝试在while循环和run方法之外声明数据变量。 Then you can call that static variable using httpReq.data 然后,您可以使用httpReq.data调用该静态变量

For reference : Static class variables in Python 供参考: Python中的静态类变量

It turns out that there are various ways of doing this. 事实证明,有多种方法可以做到这一点。 For my purposes however, (since only one thread writes to the variable, and the others read-only) I have found that using a global variable does the job. 但是,出于我的目的(因为只有一个线程写入变量,而其他线程为只读),所以我发现使用全局变量可以完成此工作。

First declare and set the variable to none, outside the thread. 首先在线程外声明并将变量设置为none。 Then within each thread, declare the variable as global: 然后在每个线程中,将变量声明为global:

#!/Library/Frameworks/Python.framework/Versions/3.5/bin/python3
# -*- coding: utf-8 -*-

from tkinter import *
import time
import urllib.request
from bs4 import BeautifulSoup
import threading
from queue import Queue

data = None

class httpReq(threading.Thread):
    def run(self):

        global data

        while True:
            url = "https://twitter.com/realDonaldTrump"
            page = urllib.request.urlopen(url)
            soup = BeautifulSoup(page, "html.parser")
            data = soup.title.text
            print(data)

x = httpReq()
x.start()

class Example(Frame):

        global data

        def __init__(self, parent):
            Frame.__init__(self, parent)
            self.parent = parent
            self.initUI()

        def initUI(self):
            self.parent.title("Example App")
            self.pack(fill=BOTH, expand=True)

            frame1 = Frame(self)
            frame1.pack(fill=X)

            lbl1 = Label(frame1, text="Title Data:", width= 20)
            lbl1.pack(side=LEFT, padx=5, pady=5)

            lbl2 = Label(frame1, text= data)
            lbl2.pack(fill=X, padx=5, expand=True)

def main():
    root = Tk()
    root.geometry("600x200")
    app = Example(root)
    root.mainloop()

if __name__ == '__main__':
    main()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM