Словарь в питоне - PullRequest
       10

Словарь в питоне

0 голосов
/ 19 июля 2011

Я создаю соединение сервер-клиент и хочу сохранить некоторую информацию в словаре, поэтому я создал глобальный словарь

global commandList
commandList = {}

И когда клиент подключается к серверу, я пытаюсь сохранить некоторую информацию следующим образом

self.clientname = str( self.client_address )
commandList[self.clientname]['lastcommand'] = GET_SETUP

но я получаю следующую ошибку

commandList[self.clientname]['isready'] = False
KeyError: "('134.106.74.22', 49194)"

ОБНОВЛЕНИЕ:

Это часть кода.

class MCRequestHandler( SocketServer.BaseRequestHandler ):

    global clientsLock, postbox, rxQueue, disconnect, isRunning, commandList
    postbox = {}    
    rxQueue = Queue.Queue()
    disconnect = {}
    commandList = {}
    clientsLock = threading.RLock()
    isRunning = {}


    def setup( self ):               
        clientsLock.acquire()        
        if len( postbox ) == 0:            
            self.clientname = 'MasterClient'
            postbox['MasterClient'] = Queue.Queue()            
            mess = str( self.client_address );            

            postbox['MasterClient'].put( self.createMessage( MASTER_CLIENT_CONNECTED, mess ) )
            print "Client name: %s" % str( self.clientname )  
            self.request.settimeout( 0.1 )                     
        else:            
            #Send message to the master client            
            self.clientname = str( self.client_address )               
            print "Client name:%s" % self.clientname

            postbox[self.clientname] = Queue.Queue()

            #Setting up the last command
            if not commandList.has_key( self.clientname ):
                commandList[self.clientname] = {}

            commandList[self.clientname]['lastcommand'] = GET_SETUP
            commandList[self.clientname]['isready'] = False            

            self.request.settimeout( COMMANDTABLE[commandList[self.clientname]['lastcommand']]['timeout'] )           

            self.transNr = 0;    
            self.start = True;
            isRunning[self.clientname] = True;

        disconnect[self.clientname] = True                   
        clientsLock.release() 

Ответы [ 5 ]

5 голосов
/ 19 июля 2011

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

Таким образом, ваш первый словарь называется commandList с ключами self.clientname. Каждое из значений в этом словаре фактически является самим словарем - или оно должно быть.

Однако вы никогда не говорите Python, что эти значения должны быть словарями, и поэтому вы получаете ошибку. Как уже указывалось, из приведенного вами кода это должно происходить и во втором фрагменте.

Есть много способов решить эту проблему, но проще всего было бы сделать что-то вроде:

if not commandlist.has_key(self.clientname):
    commandlist[self.clientname] = {} # Create an empty dictionary.

commandlist[self.clientname]['secondlevelkey'] = 'value'

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

Если вы дадите больше информации о проблеме, мы, возможно, посоветуем, как лучше ее решить.

3 голосов
/ 19 июля 2011

Вы пытаетесь прочитать значение, которого нет в требовании. Используйте defaultdict или сначала создайте commandList[self.clientname]. Также старайтесь не использовать глобальные переменные.

import collections
commandList = collections.defaultdict(dict)
2 голосов
/ 19 июля 2011

Полагаю, вам нужно выполнить двухэтапную инициализацию

self.clientname = str( self.client_address )
commandList[self.clientname] = {}
commandList[self.clientname]['lastcommand'] = GET_SETUP

Попробуйте сейчас.

0 голосов
/ 19 июля 2011

Чтобы решить проблему с KeyError, сначала необходимо создать вложенный словарь.Есть два простых варианта:

import collections
commandList = collections.defaultdict(dict) 

или без импорта чего-либо:

commandList.setdefault(self.clientname, {})['lastcommand'] = GET_SETUP

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

0 голосов
/ 19 июля 2011

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

if not self.clientname in commandList:
    commandList[self.clientname] = dict()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...