在python列表中定位不正确

时间:2013-11-29 15:57:55

标签: python

我在python程序中定位列表项有问题 我正在使用python 2.7 这是我的代码:

MAX_DOWNLOADERS = 4
from threading import Lock
import time,random,unittest
from random import randrange

class Choker:
    def __init__(self,PeerManager,max_uploads,min_uploads=None):
        self.PM = PeerManager
        self.max_uploads = max_uploads
        if min_uploads == None:
            self.min_uploads = max_uploads
        else:
            self.min_uploads = min_uploads
        self._round = 0
        self.run = True
        self.lock = Lock()
    def _unchoke_peers(self):
        while self.run:
            self._rechoke()
            self.count += 1
            time.sleep(UNCHOKE_INTERVAL)
    def _rechoke(self):
        count = 0
        preferred = []
        if self._round % 3 == 0:
            for pos,peer in enumerate(self.PM.peers):
                if peer.am_choking and peer.peer_interested:
                    self.PM.peers = self.PM.peers[pos:] + self.PM.peers[:pos]
                    break
        for i in self.PM.peers:
            if not self._snubbed(i) and i.peer_interested:
                if self.PM.completed:
                    preferred.append((i.download_speed,i))
                else:
                    preferred.append((i.upload_speed,i))
        preferred.sort(reverse=True)
        print(len(preferred))
        del preferred[self.max_uploads-1:]
        preferred = [x[1] for x in preferred]
        print(len(preferred))
        hit = False
        for peer in self.PM.peers:
            if peer in preferred:
                peer.send_unchoke()
                print('unchoking peer in preferred')
                count += 1
                print('count += 1 in preferred')
            else:
                if count < self.min_uploads or not hit:
                    peer.send_unchoke()
                    print('unchoking peer in count < self.min_uploads')
                    if peer.peer_interested:
                        count += 1
                        hit = True
                        print('count += 1 in count < self.min_uploads')
                else:
                    peer.send_choke()
                    print('choking peer')
    def _snubbed(self, peer):
        if self.PM.completed:
            return False
        return peer.is_snubbed()
    def connection_made(self, peer,p=None):
        if p == None:
            p = randrange(-2, len(self.PM.peers) + 1)
        print(p)
        self.PM.insert(max(p, 0), peer)
        self._rechoke()
    def connection_lost(self, peer):
        self.PM.peers.remove(peer)
        if peer.peer_interested and not peer.am_choking:
            self._rechoke()
    def interested(self, peer):
        if not peer.am_choking:
            self._rechoke()
    def not_interested(self, peer):
        if not peer.am_choking:
            self._rechoke()


class PM:
    def __init__(self):
        self.peers = []
        self.completed = False
        self.lock = Lock()
    def insert(self,pos,elem):
        self.lock.acquire()
        self.peers.insert(pos,elem)
        self.lock.release()
    def remove(self,elem):
        self.peers.remove(elem)


class PeeR:
    def __init__(self,upload_speed=0):
        self.peer_interested = False
        self.am_choking = True
        self.is_seeder = False
        self.upload_speed = upload_speed
        self.download_speed = 0
        self.snubbed = False
    def send_choke(self):
        self.am_choking = True
    def send_unchoke(self):
        self.am_choking = False
    def is_snubbed(self):
        return self.snubbed

当我在下面编写代码时:

pm = PM()
choker = Choker(pm,1)
c1 = PeeR()
c2 = PeeR(1)
c3 = PeeR(2)
c4 = PeeR(3)
choker.connection_made(c1)
choker.connection_made(c2,1)
choker.connection_made(c3,1)
choker.connection_made(c4,1)

在pm.peers(这是一个列表)中元素(c1,c2 ...)的位置不正确(例如c4不在位置1,c1不在位置0)。
为什么会这样? 请帮帮我。

1 个答案:

答案 0 :(得分:0)

我尝试将代码缩减到相关部分:

#! /usr/bin/python2.7

from random import randrange

class Choker:
    def __init__(self,PeerManager):
        self.PM = PeerManager
    def connection_made(self, peer,p=None):
        if p == None:
            p = randrange(-2, len(self.PM.peers) + 1)
        self.PM.insert(max(p, 0), peer)

class PM:
    def __init__(self):
        self.peers = []
    def insert(self,pos,elem):
        self.peers.insert(pos,elem)

pm = PM()
choker = Choker(pm)
c1, c2, c3, c4 = 'C1', 'C2', 'C3', 'C4'
choker.connection_made(c1)
choker.connection_made(c2,1)
choker.connection_made(c3,1)
choker.connection_made(c4,1)

print (pm.peers)

现在这会产生预期的输出(正如我所料):['C1', 'C4', 'C3', 'C2']

C1插入位置0。 在{1}处插入C2。 在{1}位置插入C3,将C2移至位置2。 在{1}位置插入C4,将C2移至第3位,将C3移至第2位。


正如Martijn指出的那样:请记住在rechoke内你重新排序你的清单:

self.PM.peers = self.PM.peers[pos:] + self.PM.peers[:pos]