2009-11-12 2 views
3

Я пытаюсь создать небольшое приложение типа сервера и задать вопрос об организации данных с помощью dicts. Сейчас я группирую данные, используя сокет соединения (в основном, чтобы проверить, откуда он идет, и для отправки данных). Что-то вроде этого: connected[socket] = account_data. В принципе, каждый подключенный человек будет иметь данные учетной записи. Поскольку некоторые поля будут использоваться для сравнения и проверки информации, например идентификатора учетной записи, я хочу ускорить работу с другим dict.Python, организующий данные с несколькими словарями

Например: чтобы найти идентификатор учетной записи с указанным выше методом, мне нужно будет использовать цикл for, чтобы просмотреть все доступные соединения в подключении, посмотреть на идентификатор учетной записи в account_data для каждого, а затем сравнить его. Кажется, это медленный способ сделать это. Если бы я мог создать dict и использовать идентификатор accountID в качестве ключа, я думаю, что это может немного ускорить работу. Проблема в том, что я планирую использовать 3 разных dicts, все упорядоченные по-разному. Некоторые данные могут часто меняться, и кажется, что больше хлопот обновлять каждый отдельный dict после изменения информации; все равно, чтобы связать их вместе?

Возможно, более простой способ объяснить, что я прошу, это: У вас есть Dict A, Dict B, Dict C и Data. Dict A, B и C содержат одни и те же данные. Я хочу, чтобы это произошло, если что-то изменилось в Data, данные в Dict A, B и C все изменились. Я могу, конечно, всегда делать dict A = данные, dict B = данные и т. Д., Но через некоторое время они будут повторяться в коде. Я знаю, что данные устанавливаются после создания dict, поэтому я не уверен, есть ли решение для этого. Я просто ищу совет по наилучшему способу организации данных в этой ситуации.

ответ

0

Если у вас есть ссылки на словари, обновление словаря будет отражено на всем с ссылкой.

Клиент подключает и удерживает гнездо, sock. Вы загружаете его аккаунт и вставляете его в connections[sock]. Затем вы держите словарь идентификаторов учетных записей (с другой стороны) со ссылками на учетные записи, accounts[account_id]. Давайте попробуем, что ...

connected = {} 
accounts = {} 

def load_account(acct): 
    return db_magic(acct)        # Grab a dictionary from the DB 

def somebody_connected(sck, acct): 
    global connected, accounts 
    account = load_account(acct) 
    connected[sck] = account       # Now we have it by socket 
    accounts[acct["accountid"]] = account    # Now we have it by account ID 

Поскольку мы назначенную account в двух разных местах, любое изменение этого словаря (в любом составе) будут отражены в другом. Так что ...

def update_username(acct_id, new_username): 
    accounts[acct_id]["username"] = new_username 

def what_is_my_username(sck): 
    sck.send(connected[sck]["username"])    # In response to GIMME_USERNAME 

Изменение мы выполняем в update_username автоматически будет подобран, когда мы делаем sck.send, потому что речь идет точно так же.

+0

Благодаря ответу каждого. Определенно имеет смысл использовать модули и классы для достижения того, что мне нужно. Попробует. – Chuck

0

Возможно, один из модулей публикации/подписки для Python может помочь вам здесь? См. this question.

2

Прежде всего, данные не подлежат репликации. Вы можете иметь 3 словаря, каждый из которых использует другой ключ, но имеющий ту же ссылку, что и его значение.

Для этого вам нужно только один раз изменить объект значения, и это будет отражено во всех словарях (точнее, поскольку словари только сохраняют ссылку, они будут обновлены).

Далее необходимо обеспечить «референциальную целостность», то есть, если конкретная запись удалена, необходимо, чтобы соответствующая запись в словаре была удалена во всех 3 словарях, и, если запись будет изменена, словари с ключом, который сейчас изменить также необходимо, чтобы запись была удалена и повторно добавлена ​​под новым ключом. Это можно сделать с помощью класса, который содержит все 3 словаря и имеет методы Add(), Remove() и (если применимо) Update().

1

Просто сделать что-то вроде:

connected[socket] = accountids[account_data.accountid] = account_data 

предполагая account_data является изменяемый объект с атрибутами, это будет ссылаться на тот же объект, как значение в обоих dicts, с разными ключами, конечно. Это не имеют быть на одном операторе, т.е .:

connected[socket] = account_data 
accountids[account_data.accountid] = account_data 

нескольких назначений в одном операторе являются просто удобство; что делает его работу так, как вы хотите, так это то, что Python универсально работает с помощью «ссылки на объект» (в назначениях, передаче аргументов, операторах возврата и т. д.).

Смежные вопросы