python говорит, что "self" - это "пропущенный обязательный позиционный аргумент", когда вызывается с asyncio? - PullRequest
0 голосов
/ 16 января 2020

Я попробую показать все функции, которые здесь используются:

def main():
    peers = [*list with many peerIDs*]
    asyncio.run(async_peerImport.importPeers(peers))
async def importPeers(peers):
    dividedPeers = divideList(peers, 250)  # this is just a function I made to split lists into lists of smaller lists
    for peers in dividedPeers:
        await asyncio.gather(*[importPeer(peerID) for peerID in peers])

async def importPeer(peerID):
    fetchPeerDataTask = asyncio.create_task(async_requests.fetchPeerData(peerID))
    getTorStatusTask = asyncio.create_task(async_requests.fetchPeerData(peerID))
    peerData = await fetchPeerDataTask
    torStatus = await getTorStatusTask
    if peerData is not None and torStatus is not None:
        db.upsertPeer(peerID, torStatus, peerData)  # the function in question
        print("peer imported:", peerID)
class db:
    def upsertPeer(self, peerID, torStatus, peerData):
        try:
            sql = "INSERT INTO peers (peerID, torStatus, peerData) VALUES (%s, %s, %s);"
            self.cursor.execute(sql, [peerID, torStatus, json.dumps(peerData)])
            print("peer inserted")
        except psycopg2.errors.UniqueViolation:
            sql = "UPDATE peers SET torStatus = %s, peerData = %s WHERE peerID = %s;"
            self.cursor.execute(sql, [torStatus, json.dumps(peerData), peerID])
            print("peer updated")
        finally:
            self.connection.commit()

Надеюсь, вы понимаете, что должно происходить? Если это сложнее, чем я думал, то скажите мне, и я добавлю кучу комментариев. Я не вижу причины, по которой это не работает, но когда я запускаю его, я получаю эту ошибку:

  File "c:\path\async_peerImport.py", line 25, in importPeer
    db.upsertPeer(peerID, torStatus, peerData)
TypeError: upsertPeer() missing 1 required positional argument: 'peerData'

Я попытался добавить какой-то случайный объект в первую позицию и переместил все остальные аргументы вверх (всего 4), и он сказал, что объект has no attribute 'connection'. Я также запустил этот upsertPeer() сам по себе, и он работает с этими 3 аргументами. Я полностью потерян здесь. Я делаю что-то не так?

Опять же, если что-то, что я пытался объяснить, не имеет смысла, просто скажите мне, и я попробую лучше.

Спасибо.

1 Ответ

1 голос
/ 16 января 2020

Этот бит:

class db:
    def upsertPeer(self, peerID, torStatus, peerData):
        # code here

определяет метод экземпляра класса. Чтобы получить к нему доступ, вам нужно получить к нему доступ через экземпляр класса db, который может выглядеть как

my_db = db()
my_db.upsertPeer(peerId, torStatus, peerData)

. В этом случае значение self равно my_db, и оно неявно передается без какого-либо вмешательства с вашей стороны.

Если вы пытаетесь создать метод класса, который можно использовать так, как это делает ваш код, попробуйте следующее:

class db:
    @classmethod
    def upsertPeer(cls, peerID, torStatus, peerData):
        # code here

Обратите внимание, что по-прежнему существует неявный первый аргумент, но это объект класса db, а не его экземпляр.

...