小能豆

在类中实现微调器类型对象作为子进程

py

我完全是个初学者,今天才开始上课,我想制作一种“微调器”对象,我可以这样调用它:我感到困惑的一件事是使用“线程”、“线程”还是“进程”。我刚刚在某处读到,一个线程实例的成本为 8MB,因为这是一个简单的文本微调器,它不值得使用大量内存。我的第一个问题是我应该使用哪个模块,第二个问题是如何在类中实现它,以便我可以像这样调用它:

spin.start() - starts it

spin.stop() -  stops it

spin.cursor_invisible() - turns the cursor invisible

spin.cursor_visible() - cursor visible!

我复制了一些代码,读了一些书,但我还是有点困惑,到目前为止,我所得到的是:我加了一些注释来表明我是多么无知。不过,我读了很多书,说真的!这是一件很难理解的事情。

spinner="▏▎▍▌▋▊▉█▉▊▌▍▎" #utf8

#convert the utf8 spinner string to a list
chars=[c.encode("utf-8") for c in unicode(spinner,"utf-8")]

class spin():   # not sure what to put in the brackets was (threading.Thread, but now im not sure whether to use processes or not)

    def __init__(self):
            super(spin, self).__init__() # dont understand what this does
            self._stop = threading.Event()

    def run (self):
            threading.Thread(target = self).run()
            pos=0
            while not self._stop:
                    sys.stdout.write("\r"+chars[pos])
                    sys.stdout.flush()
                    time.sleep(.15)
                    pos+=1
                    pos%=len(chars)

    def cursor_visible(self):
            os.system("tput cvvis")
    def cursor_invisible(self):
            os.system("tput civis")
    def stop(self):
            self._stop.set() #the underscore makes this a private variable ?
    def stopped(self):
            return self._stop.isSet()

阅读 20

收藏
2024-12-01

共2个答案

小能豆

我稍微修改了你的代码。现在可以运行了!首先是注释版本:

第一行告诉python此源文件包含utf-8字符

# -*- coding: utf-8 -*- 

然后你需要导入你最终会用到的所有内容。你不必像这样在文件顶部进行导入,但我是一个 C 语言程序员,我喜欢这种方式…

import threading
import sys
import time
import os

spinner="▏▎▍▌▋▊▉█▉▊▌▍▎" #utf8

#convert the utf8 spinner string to a list
chars=[c.encode("utf-8") for c in unicode(spinner,"utf-8")]

class spin(threading.Thread):   # not sure what to put in the brackets was (threading.Thread, but now im not sure whether to use processes or not)

线程适合这个

    def __init__(self):
        super(spin,self).__init__() # dont understand what this does

由于您正在用自己的 init 覆盖threading.Thread 的init方法,因此您需要调用父类的 init 以确保对象被正确启动。

        self._stop = False

我将其改为布尔值。threading.Event 对此来说有点过头了。

    def run (self):
        pos=0
        while not self._stop:
            sys.stdout.write("\r"+chars[pos])
            sys.stdout.flush()
            time.sleep(.15)
            pos+=1
            pos%=len(chars)

    def cursor_visible(self):
        os.system("tput cvvis")
    def cursor_invisible(self):
        os.system("tput civis")
    def stop(self):
        self._stop = True  #the underscore makes this a private variable ?

有点。它实际上不是私有的,下划线只是告诉所有人访问它是不好的形式。

    def stopped(self):
        return self._stop == True

最后对代码进行一个小测试:

if __name__ == "__main__":
    s = spin()
    s.cursor_invisible()
    s.start()
    a = raw_input("")
    s.stop()
    s.cursor_visible()

这是未注释的版本…

# -*- coding: utf-8 -*- 

import threading
import sys
import time
import os

spinner="▏▎▍▌▋▊▉█▉▊▌▍▎" #utf8

#convert the utf8 spinner string to a list
chars=[c.encode("utf-8") for c in unicode(spinner,"utf-8")]

class spin(threading.Thread):   # not sure what to put in the brackets was (threading.Thread, but now im not sure whether to use processes or not)

    def __init__(self):
        super(spin,self).__init__() # dont understand what this does
        self._stop = False

    def run (self):
        pos=0
        while not self._stop:
            sys.stdout.write("\r"+chars[pos])
            sys.stdout.flush()
            time.sleep(.15)
            pos+=1
            pos%=len(chars)

    def cursor_visible(self):
        os.system("tput cvvis")
    def cursor_invisible(self):
        os.system("tput civis")
    def stop(self):
        self._stop = True  #the underscore makes this a private variable ?
    def stopped(self):
        return self._stop == True


if __name__ == "__main__":
    s = spin()
    s.cursor_invisible()
    s.start()
    a = raw_input("")
    s.stop()
    s.cursor_visible()
2024-12-01
小能豆

看起来您正在尝试创建一个带有线程的微调器并控制光标可见性。让我帮您解开困惑,特别是关于线程和进程,以及如何在您的spin类中实现它们

1.线程与进程

  • 线程threading:当你的模块是你想要的时,使用线程
  • 流程:对于我们来说,您不需要流程

2.使用threading.Thread

  • 你可以通过子类threading.Thread来创建你的旋转
  • super():这个threading.Thread,所以super(super(spin, self).init()`Thread类是初始的
  • self._stop:这是一个事件对象,用于发出信号,表示何时停止线程。下划线表示它是常规私有的(不是严格的,只是命名约定)。

3.修复你的代码

这是使用以下方法更新的微调器类的版本threading.Thread

import threading
import time
import sys

impor

i
import os

spinner = 

"▏▎▍▌▋▊▉█▉▊▌▍▎"  # UTF8 spinner string

# Convert the UTF8 spinner string to a list of characters
chars = [c 
char
for c in spinner]



c
class Spin(threading.Thread):  # Inherit from threading.Thread


def __init__(self):
        super().__init__()  # Call the parent constructor
        self._stop = threading.Event()  
        self._stop = threadin

        se
# Event to signal when to stop

    def run(self):
        pos = 

0


while not self._stop.is_set():
            sys.stdout.write(
            sys


"\r" + chars[pos])
            sys.stdout.flush()
            time.sleep(
            sys.stdout.flush()
            time.slee

            sys.stdout.flush(


0.15)
            pos += 

1
            pos %= 
            pos 


len(chars)  # Loop through the spinner characters




def cursor_visible(self):
        os.system(

"tput cvvis")  # Show cursor

    def cursor_invisible(self):
        os.system(
        os.sys
"tput civis")  # Hide cursor

    def stop(self):
        self._stop.
        self.


set()  # Set the stop event to stop the thread

    def stopped(self):
        return self._stop.is_set()  # Return whether the thread has stopped

# Example of how to use the Spin class
spin = Spin()
spin.cursor_invisible()  
spin = Spin()
spi

spin
# Hide the cursor
spin.start()  # Start the spinner thread

# Simulate some work
time.sleep(5)

# Stop the spinner
spin.stop()
spin.join()  
spin.stop()
sp
# Wait for the thread to finish
spin.cursor_visible()  # Show the cursor again

要点:

  1. Spin:现在继承自threading.Thread,这意味着它的行为就像一个线程。
  2. run()方法:这是调用时执行的方法spin.start()。它运行微调器逻辑。
  3. stop()_stop:该stop()方法通过设置事件来向线程发出停止信号_stop
  4. cursor_visible()cursor_invisible():使用命令控制终端光标可见性tput

变更说明:

  • super().__init__():这将调用Thread构造函数来正确初始化线程功能。
  • 事件 ( _stop)_stop事件用于正常停止旋转器。它比使用time.sleep管理旋转器的行为更有效。
  • spin.start():这将在单独的线程上启动旋转器,允许其在您可以在主程序中执行其他操作时同时运行。
  • spin.stop():这表明线程停止运行。
  • spin.join():这使得主程序等待旋转线程完成后再继续。

最后说明:

  • 只应将线程用于 I/Omultiprocessing安装threading。 但线程是正确的选择
2024-12-01