Can';我无法在Python中使用我的类实例进行多处理

Can';我无法在Python中使用我的类实例进行多处理,python,python-3.x,multithreading,multiprocessing,Python,Python 3.x,Multithreading,Multiprocessing,基本上,我希望为同一对象创建几个实例,并同时分别执行它们。此示例代码: class Student: def __init__(self, username_, password_): self.username = username_ self.password = password_ self.driver = webdriver.Chrome('chromedriver.exe') def login(self):

基本上,我希望为同一对象创建几个实例,并同时分别执行它们。此示例代码:

class Student:

    def __init__(self, username_, password_):
        self.username = username_
        self.password = password_
        self.driver = webdriver.Chrome('chromedriver.exe')

    def login(self):
        # Go to students page
        self.driver.get('https://www.students.com/')
        time.sleep(2)

        # Enter username in login form
        enter_username = WebDriverWait(self.driver, 20).until(
            expected_conditions.presence_of_element_located((By.NAME, 'username')))
        enter_username.send_keys(self.username)
        # Enter password in login form
        enter_password = WebDriverWait(self.driver, 20).until(
            expected_conditions.presence_of_element_located((By.NAME, 'password')))
        enter_password.send_keys(self.password)

        # Wait to send the form
        time.sleep(2)

        # Click Log In button
        self.driver.find_elements_by_xpath("//div[contains(text(), 'Iniciar sesión')]")[0].click()

        # Wait for the form to be sent
        time.sleep(5)
        self.start_working()
        # This functions is and endless loop that simulates work

if __name__ == '__main__':
            load_dotenv()

            query = "SELECT username, password FROM students"
            cursor.execute(query)
            records = cursor.fetchall()

            print("Total number of accounts botting up ", cursor.rowcount)

            object_list = list()
            for username, password in records:
                obj = Student(username, password)
                object_list.append(obj)

            instance_list = list()
            for x in object_list:
                p = multiprocessing.Process(target=x.login)
                p.start()
                instace_list.append(p)

            for x in instance_list:
                x.join()
到目前为止,我已经让所有人创建了类的实例,但是我还不能为每个实例执行login方法

我在终端中得到了这个错误:

 (student-bot) C:\python\student-bot>Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "c:\users\alberto\appdata\local\programs\python\python37\lib\multiprocessing\spawn.py", line 99, in spawn_main
    new_handle = reduction.steal_handle(parent_pid, pipe_handle)
  File "c:\users\alberto\appdata\local\programs\python\python37\lib\multiprocessing\reduction.py", line 87, in steal_handle
    _winapi.DUPLICATE_SAME_ACCESS | _winapi.DUPLICATE_CLOSE_SOURCE)
PermissionError: [WinError 5] Acceso denegado
[13852:1860:0427/193022.541:ERROR:device_event_log_impl.cc(162)] [19:30:22.541] Bluetooth: bluetooth_adapter_winrt.cc:1055 Getting Default Adapter failed.


(学生机器人)C:\python\student bot>回溯(最近一次调用):
文件“”,第1行,在
文件“c:\users\alberto\appdata\local\programs\python\37\lib\multiprocessing\spawn.py”,第99行,在spawn\u main中
新的\u句柄=减少。偷取\u句柄(父\u pid,管道\u句柄)
文件“c:\users\alberto\appdata\local\programs\python\python37\lib\multiprocessing\reduce.py”,第87行,在steal\u句柄中
_winapi.DUPLICATE_SAME_ACCESS|_winapi.DUPLICATE_CLOSE_SOURCE)
许可错误:[WinError 5]Acceso denegado
[13852:1860:0427/193022.541:错误:设备\u事件\u日志\u impl.cc(162)][19:30:22.541]蓝牙:蓝牙适配器\u winrt.cc:1055获取默认适配器失败。

您可能想要
target=x.login
,而不是
x.login()
。否则,您将调用target.login()返回的任何内容,这些内容甚至可能不可调用。一个“正在执行”的进程实际上可能只是主线程,并且是您编码的
x.login()
,但实际上没有任何子进程在工作。显示错误消息会很有帮助。还要确保上述代码位于以以下内容开头的块中:

if __name__ == '__main__':
例如:

import multiprocessing

class Foo:
    def bar(self, i):
        print(i, flush=True)

f = Foo()

if __name__ == '__main__':
    instace_list = list()
    for i in range(3):
        p = multiprocessing.Process(target=f.bar, args=(i,))
        p.start()
        instace_list.append(p)

    for x in instace_list:
        x.join()
印刷品:

0
1
2
更新

理想情况下,您的文件结构应如下所示:

import blah, blah, blah;

class Student: # or perhaps this is imported above
    # definition of this class

def foo():
    # definition of foo

def bar():
    #d definition of bar

def query_database():
        load_dotenv()
        # obtain connection and cursor (code not shown)
        query = "SELECT username, password FROM students"
        cursor.execute(query)
        records = cursor.fetchall()

        print("Total number of accounts botting up ", cursor.rowcount)

        object_list = list()
        for username, password in records:
            obj = Student(username, password)
            object_list.append(obj)

        return object_list

if __name__ == '__main__':
        object_list = query_database() # get Student list
        with multiprocessing.Pool(processes=8) as pool:
            instance_list = list()
            for x in object_list:
                result = pool.apply_async(x.login)
                instance_list.append(result)

            for result in instance_list:
                result.get() # return value from login, which is None
更新2

<>因为<代码>登录方法似乎不是CPU绑定的进程,所以您可以考虑使用线程。此代码不必位于
\uuuuu main\uuuu
块中(尽管这样做完全正确):


我编辑了这段代码以显示更多细节,我会尝试你的答案并给出反馈,我对Python的这部分内容很陌生,这几乎让我发疯。我在帖子中修改了代码,现在每个对象都正确创建了,但在所有学生都搞砸了之后,我现在遇到了这个错误,我还没有让他们执行登录功能。我必须看看
login
功能在做什么,也许还有其余的代码。您必须意识到,对于创建的每个子进程,除了主块中的代码之外,整个源文件都会从上到下执行(这就是为什么创建子进程的代码会出现在主块中)。因此,理想情况下,文件应该只包含在调用函数和类定义之前不会执行的函数。然后,您应该有一个函数,可以在主块中调用该函数来查询数据库以获取所需的行。我会更新我的答案。我必须说,我不知道是什么导致了那个特定的错误。我再次更新了我的代码,将多处理池设置为最多8个子进程。正如您的代码现在所示,如果您有5000名学生,您将尝试创建5000个进程。我并不是说这是造成问题的原因(可能是)。但是,拥有比计算机上的CPU数量更多的进程是没有任何意义的。我的电脑有8个,所以我把号码发到了8。您的任务没有特别的CPU限制,因此您可以尝试使用线程而不是多处理。我回答了您最初的问题,即为什么您无法创建进程并成功调用登录方法,并提供了一个正常工作的演示程序。登录方法失败的原因是该方法特有的。也许它正在做的事情与同时运行的多个实例不兼容。但我认为这应该是一个新问题的主题,你发布标签,明确说明你正在使用的工具,例如
chromdriver.exe
,以及你正在运行的环境,即Windows,并获得了解这些东西的人的帮助。
from concurrent.futures import ThreadPoolExecutor

object_list = query_database() # get Student list
with ThreadPoolExecutor(max_workers=8) as executor:
    instance_list = list()
    for x in object_list:
        future = executor.submit(x.login)
        instance_list.append(future)

    for future in instance_list:
        future.get() # return value from login, which is None