Python将类附加到列表中

时间:2015-04-07 02:05:58

标签: python

我正在尝试编写一个程序来解析和加载我在媒体集合中的文件。该程序将被赋予一个目录,并开始递归扫描并将所有媒体文件(当前只是电视节目)放在一个列表中。我目前遇到的问题是它正确读取所有文件名和位置。但是当它将信息存储在列表中时,季节和剧集的信息是错误的。季节信息有点正确,因为它显示正确的季节数,但季节数是错误的。这些剧集是完全错误的。当只有一个节目被读入列表时,它会正确读取所有内容。

在底部,我缩小了我的问题并尝试使其更简单。

例如,当我只在一个节目中阅读时,这是我打印出列表时得到的结果。

    0) Stargate Atlantis
    -1) Exit
    What show do you want to look at?
    0
    0) Season 2
    1) Season 4
    2) Season 1
    3) Season 3
    4) Season 5
    -1) Exit
    What season do you want to look at?
    2
    0) Stargate Atlantis - S05e16 - Brain Storm.mkv
    1) Stargate Atlantis - S05e17 - Infection.mkv
    2) Stargate Atlantis - S05e18 - Identity.mkv
    3) Stargate Atlantis - S05e19 - Vegas.mkv
    4) Stargate Atlantis - S05e20 - Enemy At The Gate.mkv
    5) Stargate Atlantis - S05e01 - Search And Rescue.mkv
    6) Stargate Atlantis - S05e02 - The Seed.mkv
    7) Stargate Atlantis - S05e03 - Broken Ties.mkv
    8) Stargate Atlantis - S05e04 - The Daedalus Variations.mkv
    9) Stargate Atlantis - S05e05 - Ghost In The Machine.mkv
    10) Stargate Atlantis - S05e06 - The Shrine.mkv
    11) Stargate Atlantis - S05e07 - Whispers.mkv
    12) Stargate Atlantis - S05e08 - The Queen.mkv
    13) Stargate Atlantis - S05e09 - Tracker.mkv
    14) Stargate Atlantis - S05e10 - First Contact.mkv
    15) Stargate Atlantis - S05e11 - The Lost Tribe.mkv
    16) Stargate Atlantis - S05e12 - Outsiders.mkv
    17) Stargate Atlantis - S05e13 - Inquisition.mkv
    18) Stargate Atlantis - S05e14 - The Prodigal.mkv
    19) Stargate Atlantis - S05e15 - Remnants.mkv
    -1) Exit
    What episode do you want to look at?

除了os.walk半随机地读取它们之外,一切都很好。但是,当我阅读更多的电视节目时,它开始搞砸了。以下是我在两个电视节目中看到的情况。

0) Stargate Atlantis
1) Brooklyn Nine-Nine
-1) Exit
What show do you want to look at?
0 # I selected option 0 (Stargate Atlantis)
0) Season 1
1) Season 2
2) Season 1
3) Season 3
4) Season 5
-1) Exit
What season do you want to look at?
0
0) Brooklyn Nine-Nine - S02E02 - Chocolate Milk.mp4
1) Brooklyn Nine-Nine - S02E01 - Undercover.mp4
2) Brooklyn Nine-Nine - S02E04 - Halloween II.mp4
3) Brooklyn Nine-Nine - S02E03 - The Jimmy Jab Games.mp4
4) Brooklyn Nine-Nine - S01E01 - Pilot.mkv
5) Brooklyn Nine Nine - S01E02 - HDTV x264 LOL.mp4
6) Brooklyn Nine Nine - S01E04 - HDTV x264 LOL.mp4
7) Brooklyn Nine Nine - S01E07 - 480p HDTV x264mSD.mkv
8) Brooklyn Nine Nine - S01E08 - 480p HDTV x264mSD.mkv
9) Brooklyn Nine Nine - S01E09 - 480p HDTV x264mSD.1.2.mkv
10) Brooklyn Nine Nine - S01E10 - 480p HDTV x264mSD.1.mkv
11) Brooklyn Nine Nine - S01E11 - 480p HDTV x264mSD.1.2.mkv
12) Brooklyn Nine-Nine - S01E18 - HDTV x264 KILLERS.mp4
13) Brooklyn Nine-Nine - S01E13 - HDTV x264 EXCELLENCE.mp4
14) Brooklyn Nine-Nine - S01E14 - HDTV x264 EXCELLENCE.mp4
15) Brooklyn Nine-Nine - S01E15 - HDTV x2642HD.mp4
16) Brooklyn Nine-Nine - S01E16 - REAL HDTV x264 EXCELLENCE.mp4
17) Brooklyn Nine-Nine - S01E17 - PROPER HDTV x264KILLERS.mp4
18) Brooklyn Nine-Nine - S01E19 - HDTV x2642HD.mp4
19) Brooklyn Nine-Nine - S01E20 - PROPER HDTV x2642HD.mp4
20) Brooklyn Nine-Nine - S01E21 - HDTV x264EXCELLENCE.mp4
21) Brooklyn Nine-Nine - S01E22 - HDTV x264EXCELLENCE.mp4
22) NULL
23) NULL
24) NULL
25) NULL
26) NULL
27) NULL
28) NULL
29) NULL
30) NULL
31) NULL
32) NULL
33) NULL
34) NULL
35) NULL
36) NULL
37) NULL
38) NULL
39) NULL
40) NULL
41) NULL
42) NULL
-1) Exit
What episode do you want to look at?

一旦我添加了更多的电视节目,情况会变得更糟,如果我尝试查看第一季,它通常会上升到选项433,其中90%为NULL。

这是我现在的代码

__author__ = "michael"
import socket, thread, os, time, tvdb_api

host = "127.0.0.1"
port = 9876
connections = 0


class media ():
    tv = []
    index = {}
    budget = 0
    numoftvshows = 0
    exit = 0
    # add existing will not add any files that contain these extensions
    ignore_list = [".html", ".url", ".txt", ".db", ".srt", ".jpg", ".png", ".docx", ".doc", ".rar", ".zip", ".tar", ".7z", ".dat", ".bmp", ".gif", ".psd", ".tga", ".tif", ".pdf", ".xlr", ".xls", ".xlsx", ".jar", ".exe", ".sav", ".rom", ".php", ".part", ".crdownload", ".msi", ".torrent", ".idx", ".sub", ".nfo"]


class Tvshows():
    name = 'NULL'
    seasons = []
    curseason = 0
    numofseasons = 0
    nextep = 0
    showstat = 0
    rootdir = 'NULL'


class Seas():
    exist = 0
    complete = 0
    episodes = []
    numofeps = 0
    realnum = 1


class epi():
    releasedate = []
    status = 0
    filename = 'NULL'
    realnum = 0


def initiliazer(mdata):
    # setting counter variables to 0
    i = 0
    j = 0
    # checks to see if data file is empty
    # if data file is empty skips loading and goes to menu
    if os.stat("tvdata.dat").st_size == 0:
        print "tvdata.dat is empty skipping load"
        return mdata
    else:
        # opens files and uses '|' as a delimeter
        print "Loading data please wait...."
        file = open("tvdata.dat", "rw")
        for line in file:
            fields = line.split('|')
            # appends a new show everytime a new one is found
            mdata.tv.append(Tvshows())
            mdata.numoftvshows += 1
            mdata.tv[j].name = fields[i]
            mdata.index[mdata.tv[j].name] = j
            i += 1
            mdata.tv[j].curseason = int(fields[i])
            i += 1
            mdata.tv[j].numofseasons = int(fields[i])
            i += 1
            mdata.tv[j].nextep = int(fields[i])
            i += 1
            mdata.tv[j].showstat = int(fields[i])
            i += 1
            mdata.tv[j].rootdir = fields[i]
            i += 1
            n = 0
            while n < mdata.tv[j].numofseasons:
                # appends a new season every time a new one is added
                mdata.tv[j].seasons.append(Seas())
                mdata.tv[j].seasons[n].realnum = int(fields[i])
                i += 1
                mdata.tv[j].seasons[n].numofeps = int(fields[i])
                i += 1
                k = 0
                while k < mdata.tv[j].seasons[n].numofeps:
                    # appends a new episode every time a new one is added
                    mdata.tv[j].seasons[n].episodes.append(epi())
                    mdata.tv[j].seasons[n].episodes[k].filename = fields[i]
                    i += 1
                    mdata.tv[j].seasons[n].episodes[k].status = int(fields[i])
                    i += 1
                    k += 1
                n += 1
            j += 1
    print "Loading data complete"
    file.close()
    return mdata


def printdata(mdata, client):
    i = 0
    while i < mdata.numoftvshows:
        client.send(str(i))
        client.send(") ")
        client.send(mdata.tv[i].name)
        client.send("\n")
        i += 1
    client.send("-1) Exit\n")
    client.send("What show do you want to look at?\n")
    showpick = client.recv(4096)
    showpick = showpick.rstrip()
    if showpick == "-1":
        return
    showpick = int(showpick)

    i = 0
    while i < mdata.tv[showpick].numofseasons:
        client.send(str(i))
        client.send(") Season ")
        client.send(str(mdata.tv[showpick].seasons[i].realnum))
        client.send("\n")
        i += 1
    client.send("-1) Exit\n")
    client.send("What season do you want to look at?\n")
    seaspick = client.recv(4096)
    seaspick = seaspick.rstrip()
    if seaspick == "-1":
        return
    seaspick = int(seaspick)

    i = 0
    while i < mdata.tv[showpick].seasons[seaspick].numofeps - 1:
        client.send(str(i))
        client.send(") ")
        client.send(mdata.tv[showpick].seasons[seaspick].episodes[i].filename)
        client.send("\n")
        i += 1
    client.send("-1) Exit\n")
    client.send("What episode do you want to look at?\n")
    epipick = client.recv(4096)
    epipick = epipick.rstrip()
    if epipick == -1:
        return
    return
    epipick = int(epipick)


def addexistshow(mdata, client):
    nameofshow = ">>NULL<<"  # added the >><< to make sure this never matches a show name
    seascheck = "Season #"  # makes sure this is not found by default
    client.send("What directory are your files located in?\n")
    workdir = client.recv(4096)
    workdir = workdir.rstrip()
    errnum = 0
    k = -1
    for cur, dir, filenames in os.walk(workdir):
        rootdir = cur
        if nameofshow not in cur and cur != workdir and cur[0] != '.':
            strlen = len(workdir)
            cur = cur[strlen:]
            if cur[0] == '/':
                cur = cur[1:]
            mdata.tv.append(Tvshows())
            mdata.numoftvshows += 1
            k += 1
            mdata.tv[k].name = cur
            nameofshow = cur
            mdata.tv[k].rootdir = rootdir
            i = -1
            seascheck = "Season #"
            client.send(cur)
            client.send("\n")
        elif seascheck not in cur and cur != workdir:
            strlen = len(workdir + '/' + nameofshow + '/')
            cur = cur[strlen:]
            if cur != seascheck and "season" in cur.lower():
                i += 1
                mdata.tv[k].seasons.append(Seas())
                mdata.tv[k].numofseasons += 1
                mdata.tv[k].seasons[i].exist = 1
                mdata.tv[k].seasons[i].realnum = int(cur[7:])
                seascheck = cur
            if "season" in cur.lower():
                mdata.tv[mdata.numoftvshows - 1].seasons[i].realnum = int(seascheck[7:])
                mdata.tv[mdata.numoftvshows - 1].seasons[i].numofeps += 1
                mdata.tv[mdata.numoftvshows - 1].seasons[i].exist = 1
            client.send(cur)
            client.send("\n")
        if seascheck in cur:
            j = 0
            for line in filenames:
                good = True
                for ext in mdata.ignore_list:
                    if ext in line[-6:]:
                        good = False
                        client.send("[*] Skipping ")
                        client.send(ext)
                        client.send(" found in ")
                        client.send(line)
                        client.send("\n")
                if good is True:
                    try:
                        #print "tv =", k, "season =", i, "episode =", j
                        mdata.tv[k].seasons[i].episodes.append(epi())
                        epname = line.split(",")
                        realnumbuff = epname[0].split(" - ")
                        realnumbuff = int(realnumbuff[1][4:])
                        mdata.tv[k].seasons[i].episodes[j].realnum = realnumbuff
                        mdata.tv[k].seasons[i].episodes[j].filename = epname[0]
                        mdata.tv[k].seasons[i].episodes[j].status = 1
                        mdata.tv[k].seasons[i].numofeps += 1
                        client.send(mdata.tv[k].seasons[i].episodes[j].filename)
                        client.send("\n")
                        if mdata.tv[k].seasons[i].episodes[j].filename == "Brooklyn Nine-Nine - S02E03 - The Jimmy Jab Games.mp4":
                            return mdata
                        j += 1
                    except Exception as e:
                        client.send("[!] Error as ")
                        client.send(str(e))
                        client.send("\n")
                        errnum += 1
    #print mdata.tv[9].name
    #print mdata.tv[25].seasons[3].episodes[190].filename
    if errnum > 0:
        client.send("\n[!] WARNING - A total of ")
        client.send(errnum)
        client.send(" errors were encountered! This could cause problems proceed with caution.\n")
    return mdata


def writedatafile( mdata):
    file = open("tvdata.da", "w")
    for i in xrange(0, mdata.numoftvshows):
        file.write(mdata.tv[i].name)
        file.write("|")
        file.write(str(mdata.tv[i].curseason))
        file.write("|")
        file.write(str(mdata.tv[i].numofseasons))
        file.write("|")
        file.write(str(mdata.tv[i].nextep))
        file.write("|")
        file.write(str(mdata.tv[i].showstat))
        file.write("|")
        file.write(mdata.tv[i].rootdir)
        for j in xrange(0, mdata.tv[i].numofseasons):
            file.write(str(mdata.tv[i].seasons[j].realnum))
            file.write("|")
            file.write(str(mdata.tv[i].seasons[j].numofeps))
            file.write("|")
            for k in xrange(0, mdata.tv[i].seasons[j].numofeps):
                file.write(mdata.tv[i].seasons[j].episodes[k].filename)
                file.write("|")
                file.write(str(mdata.tv[i].seasons[j].episodes[k].status))
                file.write("|")
    return mdata


def addnewshow(mdata):
    show = raw_input("What show do you want to add?\n")



def menu( mdata, client):
    client.send('----Media Get----\n\n')
    client.send(' 1) Add a new show    2) Add an existing show\n')
    client.send(' 3) Print Database    4) Rewrite data file\n')
    client.send('-1) Exit Menu        -2) Exit program completely\n')
    pick = client.recv(4096)
    pick = pick.rstrip()
    if pick == "1":
        addnewshow(mdata)
    elif pick == "2":
        addexistshow(mdata, client)
    elif pick == "3":
        printdata(mdata, client)
    elif pick == "4":
        writedatafile(mdata)
    elif pick == "-1":
        mdata.exit = 1
    elif pick == "-2":
        mdata.exit = 1
    return mdata


def t_handle(client, address, s, mdata):
    while mdata.exit != 1:
        mdata = menu(mdata, client)
    client.send("[*] closing connection\n")
    client.close
    time.sleep(2)
    thread.exit()


def main():
    mdata = media()
    mdata = initiliazer(mdata)
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind((host, port))
    s.listen(1)
    connections = -1
    while 1:
        connections += 1
        print "Number of clients connected", connections
        client, address = s.accept()
        thread.start_new_thread(t_handle,(client,address, s, mdata))


if __name__ == '__main__':
    main()

---缩小代码---

我相信问题出在我的班级声明中,以及我从文件中读取show数据的地方。当我使用调试器查看代码时,所有季节都位于所有节目的相同内存地址中。我认为这是因为我将一个类附加到列表错误但我不确定我做错了什么。

    class media ():
    tv = []
    index = {}
    budget = 0
    numoftvshows = 0
    exit = 0
    # add existing will not add any files that contain these extensions
    ignore_list = [".html", ".url", ".txt", ".db", ".srt", ".jpg", ".png", ".docx", ".doc", ".rar", ".zip", ".tar", ".7z", ".dat", ".bmp", ".gif", ".psd", ".tga", ".tif", ".pdf", ".xlr", ".xls", ".xlsx", ".jar", ".exe", ".sav", ".rom", ".php", ".part", ".crdownload", ".msi", ".torrent", ".idx", ".sub", ".nfo"]


class Tvshows():
    name = 'NULL'
    seasons = []
    curseason = 0
    numofseasons = 0
    nextep = 0
    showstat = 0
    rootdir = 'NULL'


class Seas():
    exist = 0
    complete = 0
    episodes = []
    numofeps = 0
    realnum = 1


class epi():
    releasedate = []
    status = 0
    filename = 'NULL'
    realnum = 0


def addexistshow(mdata, client):
    nameofshow = ">>NULL<<"  # added the >><< to make sure this never matches a show name
    seascheck = "Season #"  # makes sure this is not found by default
    client.send("What directory are your files located in?\n")
    workdir = client.recv(4096)
    workdir = workdir.rstrip()
    errnum = 0
    k = -1
    for cur, dir, filenames in os.walk(workdir):
        rootdir = cur
        if nameofshow not in cur and cur != workdir and cur[0] != '.':
            strlen = len(workdir)
            cur = cur[strlen:]
            if cur[0] == '/':
                cur = cur[1:]
            mdata.tv.append(Tvshows())
            mdata.numoftvshows += 1
            k += 1
            mdata.tv[k].name = cur
            nameofshow = cur
            mdata.tv[k].rootdir = rootdir
            i = -1
            seascheck = "Season #"
            client.send(cur)
            client.send("\n")
        elif seascheck not in cur and cur != workdir:
            strlen = len(workdir + '/' + nameofshow + '/')
            cur = cur[strlen:]
            if cur != seascheck and "season" in cur.lower():
                i += 1
                mdata.tv[k].seasons.append(Seas())
                mdata.tv[k].numofseasons += 1
                mdata.tv[k].seasons[i].exist = 1
                mdata.tv[k].seasons[i].realnum = int(cur[7:])
                seascheck = cur
            if "season" in cur.lower():
                mdata.tv[mdata.numoftvshows - 1].seasons[i].realnum = int(seascheck[7:])
                mdata.tv[mdata.numoftvshows - 1].seasons[i].numofeps += 1
                mdata.tv[mdata.numoftvshows - 1].seasons[i].exist = 1
            client.send(cur)
            client.send("\n")
        if seascheck in cur:
            j = 0
            for line in filenames:
                good = True
                for ext in mdata.ignore_list:
                    if ext in line[-6:]:
                        good = False
                        client.send("[*] Skipping ")
                        client.send(ext)
                        client.send(" found in ")
                        client.send(line)
                        client.send("\n")
                if good is True:
                    try:
                        #print "tv =", k, "season =", i, "episode =", j
                        mdata.tv[k].seasons[i].episodes.append(epi())
                        epname = line.split(",")
                        realnumbuff = epname[0].split(" - ")
                        realnumbuff = int(realnumbuff[1][4:])
                        mdata.tv[k].seasons[i].episodes[j].realnum = realnumbuff
                        mdata.tv[k].seasons[i].episodes[j].filename = epname[0]
                        mdata.tv[k].seasons[i].episodes[j].status = 1
                        mdata.tv[k].seasons[i].numofeps += 1
                        client.send(mdata.tv[k].seasons[i].episodes[j].filename)
                        client.send("\n")
                        if mdata.tv[k].seasons[i].episodes[j].filename == "Brooklyn Nine-Nine - S02E03 - The Jimmy Jab Games.mp4":
                            return mdata
                        j += 1
                    except Exception as e:
                        client.send("[!] Error as ")
                        client.send(str(e))
                        client.send("\n")
                        errnum += 1
    #print mdata.tv[9].name
    #print mdata.tv[25].seasons[3].episodes[190].filename
    if errnum > 0:
        client.send("\n[!] WARNING - A total of ")
        client.send(errnum)
        client.send(" errors were encountered! This could cause problems proceed with caution.\n")
    return mdata

这个项目的目的是在他们出来上课时自动合法购买新电视节目。我相信我的班级做错了,这导致我一遍又一遍地覆盖同一季节列表,而不是每个节目和季节都有自己独特的列表。

我非常感谢您能给我的任何帮助,如果需要更多信息,请告诉我,我会尽我所能。

1 个答案:

答案 0 :(得分:1)

这是初始化类成员的错误方法:

class Tvshows():
    name = 'NULL'
    seasons = []
    curseason = 0
    ...

这些成员将是类本身的属性,而不是单个实例。这将导致可变值的问题:当您稍后调用some_instance.seasons.append(x)时,它将被附加到所有实例共享的列表中。

您应该初始化__init__方法中的所有成员,这些成员将在每个实例上单独调用:

class Tvshows():
    def __init__(self):
        self.name = 'NULL'
        self.seasons = []
        self.curseason = 0
        ...