在循环期间附加的列表似乎在python中进行了优化?

时间:2015-06-29 13:56:46

标签: python list

我有一个客户端 - 服务器应用程序,客户端收集一些信息,并将json序列化并发送到服务器,服务器稍后将其存储在数据库中。在服务器的tcp服务模块中,我有代码从列表中的字符串加载json对象,然后将它们附加到另一个列表中这样(查看bind_and_listen内的循环,以for client in clients开头):

""" TCP Server before the main database. """

import socket
import sys
import logging
import json

import structs.client_data as cl_data
import db.register as register

cursor = register.cursor

client_list = []
domain_list = []

# connection constants
HOST = None
PORT = None


def config_server(host, port):
    """ Configure the server's address and port. """
    if not host:
       logging.warning("HOST not supplied in the configuration file.")
       sys.exit(-1)

    if not port:
       logging.warning("PORT not supplied in the configuration file.")
       sys.exit(-1)

    global HOST
    global PORT

    HOST = host
    PORT = int(port)


def handle_files_question(request):
    """ Read the file policy from the database for the server that sent it. 

    Params:
    @request: The request as sent from the server.
    """
    index    = request.find(':')
    hostname = request[index + 1:]

    return register.query_file_policy(hostname)


def handle_size_question(request):
    """ Read the size policy from the database for the server that sent it.

    Params:
    @request: The request as sent from the server.
    """
    index    = request.find(':')
    hostname = request[index + 1:]

    return register.query_size_policy(hostname)



def bind_and_listen():
    """ Bind the server to the socket, and listen for incoming connections. """

    serv = None

    # create the socket
    try:
        serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    except socket.error, v:
        message = "Failed to create a socket: Message is {} and error code is {}"
        errno, errormsg = v  # is a (errno, message) tuple
        message = message.format(errormsg, errno)
        logging.error(message)
        print message
        sys.exit(-1) 

    # bind out socket to the address
    try:
        serv.bind((HOST, PORT)) # the double parens are to create a tuple with one element
    except socket.error, msg:
        message = "Binding of the socket failed. Error Code : {} Message: {}."
        message = message.format(msg[0], msg[1])
        logging.error(message)
        print message
        sys.exit(-2)

    serv.listen(5)    # 5 is the maximum number of queued connections we will allow
    logging.info("Server is now listening on port %d" % (PORT,))

    # we have the try block here only to facilitate the finally block
    # that follows, so that we can reliably close the database everytime
    # we have to close the program, but we don't have an exception raised
    # everytime a client disconnects, the db is closed, and the networking 
    # module attempts to use the cursor of the expired connection.
    try:
        while True:
            conn, addr = serv.accept() 
            hostname   = None
            output     = str()

            # this is the code handling the first policy question, regarding files
            # 256 bytes should be enough to specify the question and hostname
            res    = conn.recv(256)
            output = res

            if output.startswith('files'):
                files = handle_files_question(output)
                conn.send(str(files))

            # reset the output string
            output = str()

            # repeat the above procedure for the size policy question
            res    = conn.recv(256)
            output = res

            if output.startswith('size'):
                size = handle_size_question(output)
                conn.send(str(size))

            # reset the output string
            output = str()

            # handle the rest of the data that the client sends
            # (mainly, the clients and domains lists)
            while True:
                res = conn.recv(1024)
                if not res:
                    break
                output += res

            # at this point, we assume that we have the full output string
            # so we will split it to a list of strings representing the json
            # representation of our clients
            output        = output.split('---')
            domains_index = output.index('Domains_list')

            clients = output[0:domains_index - 1]  # -1 to compensate for a newline in the list
            print clients
            domains = output[domains_index + 1:-1]

            hostname = output[0].split()[1]
            clients  = clients[2:-1] # ignoring the hostname and the Clients_list delimiter

            for client in clients:
                jason = json.loads(client)
                client            = cl_data.Client(jason['client_id'], jason['login'], jason['pname'], jason['email'])
                client.files      = jason['files']
                client.size       = jason['size']
                client.size_human = jason['size_human']
                client.domains    = jason['domains']
                client.domain_num = jason['domain_num']
                client_list.append(client)

            # the code below seems to prevent the problem?
            #for client in client_list:
            #    print client.pname

            for domain in domains:
                jason = json.loads(domain)
                domain = cl_data.DomainName(jason['domain_id'], jason['name'], jason['client_id'])
                domain_list.append(domain)


            conn.close()
            register.update_clients(hostname, client_list)
            register.update_domains(hostname, domain_list)
            logging.info("Connection from %s is terminated." % (addr,))
    except KeyboardInterrupt:
        message  = "\nCtrl + C was pressed, and an interruption signal has been registered."
        message += " Terminating the server now."
        logging.info(message)
        print message
    finally:
        register.close_connection()

此时一切都很好。完成循环后,我使用client_list使用以下代码更新SQL数据库:

register.update_clients(hostname, client_list)

问题是,如果我在上面的代码之前添加print len(client_list)之类的东西,我会得到1,除非我做了类似的事情:

for client in client_list:
    print client.email

在这种情况下,我得到列表中包含应该包含的所有对象(约180左右)。

从上面开始,我收集的是,由于某些我无法理解的原因,列表追加被优化了,除非我强制列表在第一个循环结束后立即迭代。有没有人对此有任何见解?这是标准的行为吗?我做错了什么?这是一个错误还是什么?

根据口译员和python 2.7.9debian 8 (jessie)/etc/os-release

(我知道我可以使用dis模块进一步调查它,但是当我尝试将它导入python解释器时,模块的编写方式向我提供了一些ImportError < / p>

0 个答案:

没有答案