如何在Python中删除函数?

0 投票
1 回答
3800 浏览
提问于 2025-04-18 00:05

我有一个游戏服务器,还有一个工具,我用这个工具来生成crc32和时间戳,并把它们保存到文件里。但是这个脚本文件有很多功能,我并不想用那些功能。我只需要获取crc32、时间戳并保存到文件。

我尝试删除那些功能,但总是出错,要么是语法错误,要么是其他错误。我试了100次了……所以我想在这里发帖,也许有人能帮我。

#!/usr/local/bin/python

from urllib import urlopen
from datetime import date
import sys
import os
import zlib
import getopt
import csv
import zipfile

#
# Utility functions
#

def FindFilesByExt(path, ext):
    ext = ext.lower()

    for root, dirs, files in os.walk(path):
        for name in files:
            if name[-len(ext):].lower() == ext:
                yield os.path.join(root, name)

def GetFileCrc32(filename):
    crc = 0
    for line in open(filename, "rb"):
        crc = zlib.crc32(line, crc)

    return "%x" % (crc & 0xffffffff)

def FormatName(filename):
    if filename[:2] == ".\\":
        filename = filename[2:]

    return filename.replace("\\", "/")

def GetLastModifiedTime(filename):
    # http://support.microsoft.com/kb/167296
    # How To Convert a UNIX time_t to a Win32 FILETIME or SYSTEMTIME
    EPOCH_AS_FILETIME = 116444736000000000  # January 1, 1970 as MS file time
    HUNDREDS_OF_NANOSECONDS = 10000000

    return EPOCH_AS_FILETIME + long(os.path.getmtime(filename)) * HUNDREDS_OF_NANOSECONDS

#
# Real code
#

class Patch:
    def __init__(self):
        self.name = None
        self.patch_url = None

        # Patch file list
        self.file_dict = dict()
        self.file_list = None

    def SetName(self, name):
        self.name = name

    def SetPatchUrl(self, url):
        self.patch_url = url

    def AddFilesFromPatchUrl(self):
        for line in urlopen(self.patch_url):
            line = line.split()
            print line
            line[4] = FormatName(line[4])
            self.file_dict[line[4].lower()] = line

    def AddFile(self, filename):
        filename = FormatName(filename)
        mtime = GetLastModifiedTime(filename)

        #
        # Format is as following:
        # unpacked_crc unpacked_size low_last_edit high_last_edit path
        #

        self.file_dict[filename.lower()] = [GetFileCrc32(filename),
                            "%d" % (os.path.getsize(filename)),
                            "%d" % (mtime >> 32),
                            "%d" % (mtime & 0xffffffff), filename]

        # Sorted list no longer contains all files. Invalidate it.
        self.file_list = None

    def GetCrcList(self):
        self.__SortFileList()

        output = ""
        for entry in self.file_list:
            output += (" ".join(entry) + "\n")

        return output

    def __SortFileList(self):
        if not self.file_list:
            self.file_list = [self.file_dict[key] for key in self.file_dict]
            self.file_list.sort(key=lambda entry: entry[4].lower()) # 4 = filename index


kPatchConfigFieldNames = ["Name", "Url"]

def GetPatchInstance(filename, desiredName):
    with open(filename, 'r') as file:
        reader = csv.DictReader(file, fieldnames=kPatchConfigFieldNames, dialect='excel-tab')
        reader.next()

        for row in reader:
            if row["Name"] == desiredName:
                patch = Patch()
                patch.SetName(row["Name"])
                patch.SetPatchUrl(row["Url"])
                return patch

    raise RuntimeError("Failed to find %s!" % (desiredName))
    return None

def WriteXmlFile(filename, files):
    file = open(filename, "wb+")

    file.write('<ScriptFile>')

    for f in files:
        file.write('\t<CreateLz Input="%s" Output="%s.lz" />\n' % (f, f))

    file.write('</ScriptFile>')

def main(argv):
    #
    # Parse command-line arguments
    #

    optlist, args = getopt.getopt(argv[1:], 'a:f:p:', ['archive=', 'file=', 'patchcfg='])

    archives = list()
    files = list()
    patchConfigName = None

    for name, value in optlist:
        if name == "--archive" or name == "-a":
            files.append("pack/" + value + ".eix")
            files.append("pack/" + value + ".epk")
        elif name == "--file" or name == "-f":
            files.append(value)
        elif name == "--patchcfg" or name == "-p":
            patchConfigName = value

    #
    # Decide over patch-config to use...
    #

    patch = GetPatchInstance("PatchConfig.txt", patchConfigName)

    # Add already existing files
    patch.AddFilesFromPatchUrl()

    # Process files
    WriteXmlFile("make_patch.xml", files)

    os.system("FileArchiver make_patch.xml")

    os.unlink("make_patch.xml")

    # Create patch ZIP
    zip = zipfile.ZipFile("PATCH_%s_%s.zip" % (patchConfigName, date.today().strftime("%m%d%Y")), "w", zipfile.ZIP_DEFLATED)

    for file in files:
        patch.AddFile(file)
        file = file + ".lz"
        zip.write(file)
        os.unlink(file)

    zip.writestr("crclist", patch.GetCrcList())

    zip.close()

main(sys.argv)

如果你想试试这个脚本,可以在命令提示符下运行:

python make_patch.py -f filename.extension -p patch_live

要运行这个脚本,需要在同一个文件夹里有PatchConfig.txt文件

make_patch.py

PatchConfig.txt

1 个回答

0

当你从脚本中删除函数时,必须确保你删除的函数在代码的其他地方没有被调用。

举个例子,假设你的脚本是这样的:

def foo(x):
    return x*x

def banana():
    return "Peel"

def bar():
    return "My " + banana()

i = int(raw_input("Please enter a number to be squared: "))

print foo(i) #prints the number you entered, squared

print banana() #prints "Peel"

print bar() #prints "My Peel"

那么,如果我只想保留函数 bar()foo(x) 的功能,而不需要使用函数 banana(),我可以删除这些函数。但是,如果我 删除函数 banana(),就会出现错误,像这样:

def foo(x):
    return x*x

#deleted banana()

def bar():
    return "My " + banana()

i = int(raw_input("Please enter a number to be squared: "))

print foo(i) #prints the number you entered, squared

print banana() #gives an error because banana() is not defined

print bar() #not executed because of the above error.

我们来删除 print banana() 看看这样能不能解决问题。

def foo(x):
    return x*x

#deleted banana()

def bar():
    return "My " + banana()

i = int(raw_input("Please enter a number to be squared: "))

print foo(i) #prints the number you entered, squared

#deleted print banana()

print bar() #error because the bar() function calls the deleted banana() function

这仍然不行,因为 bar() 函数在这里调用了 banana()

def bar():
    return "My " + banana()

当你删除一个函数时,必须删除 所有对该函数的调用,无论它在哪里。如果不这样做,Python 会尝试调用一个不存在的函数,从而出现错误。下面是正确的示例代码,用于删除 banana() 的所有痕迹:

def foo(x):
    return x*x

#deleted banana()

def bar():
    return "My " + "Peel" # removed banana()

i = int(raw_input("Please enter a number to be squared: "))

print foo(i) #prints the number you entered, squared

#deleted print banana()

print bar() #prints "My Peel"

在你应用这个到你的代码时,确保你删除的函数没有被任何你想保留的函数直接调用(比如 crc32 函数)。在我的例子中,如果你想保留 bar() 函数,实际上 banana() 函数是运行 bar() 所必需的,所以你不应该删除它。

在你的代码中,AddFile 方法是你调用 GetFileCrc32() 时使用的。正如你所看到的,FormatName()GetLastModifiedTime() 也被调用了。这些函数对 GetFileCrc32() 的正常工作是必要的,所以你 不应该 删除它们。

 def AddFile(self, filename):
    filename = FormatName(filename)
    mtime = GetLastModifiedTime(filename)

    #
    # Format is as following:
    # unpacked_crc unpacked_size low_last_edit high_last_edit path
    #

    self.file_dict[filename.lower()] = [GetFileCrc32(filename),
                        "%d" % (os.path.getsize(filename)),
                        "%d" % (mtime >> 32),
                        "%d" % (mtime & 0xffffffff), filename]

    # Sorted list no longer contains all files. Invalidate it.
    self.file_list = None

希望这对你有帮助!

撰写回答