2

我正在尝试编写一个类似于内置函数和我见过的其他一些“成熟的”Python 东西的类。我的 Pythonic 教育在课堂方面有点参差不齐,我担心我把这一切都搞混了。

我想创建一个用作一种存储库的类,其中包含未处理文件(及其名称)的字典和已处理文件(及其名称)的字典。我想实现一些其他(子?)类来处理诸如打开和处理文件之类的事情。文件处理类应该能够更新主类中的字典。我还希望能够直接调用各种子模块,而不必单独实例化所有内容,例如:

import Pythia
p = Pythia()
p.FileManager.addFile("/path/to/some/file")

甚至

Pythia.FileManager.addFile("/path/to/some/file")

我一直在寻找诸如此类的东西@classmethodsuper但我不能说我完全理解它。我也开始怀疑我可能有整个继承链向后 - 我认为我的主类实际上应该是处理和处理类的子类。我也想知道这是否会作为一个包更好地工作,但这是一个单独的、非常令人生畏的问题。

到目前为止,这是我的代码:

#!/usr/bin/python

import re
import os
class Pythia(object):
    def __init__(self):
        self.raw_files = {}
        self.parsed_files = {}
        self.FileManger = FileManager()
    def listf(self,fname,f):
        if fname in self.raw_files.keys():
            _isRaw = "raw"
        elif fname in self.parsed_files.keys():
            _isRaw = "parsed"
        else:
            return "Error: invalid file"
        print "{} ({}):{}...".format(fname,_isRaw,f[:100])

    def listRaw(self,n=None):
        max = n or len(self.raw_files.items())
        for item in self.raw_files.items()[:max]:
            listf(item[0],item[1])

    def listParsed(self,n=None):
        max = n or len(self.parsed_files.items())
        for item in self.parsed_files.items()[:max]:
            listf(item[0],item[1])

class FileManager(Pythia):
    def __init__(self):
        pass
    def addFile(self,f,name=None,recurse=True,*args):
        if name:
            fname = name
        else:
            fname = ".".join(os.path.basename(f).split(".")[:-1])
        if os.path.exists(f):
            if not os.path.isdir(f):
                with open(f) as fil:
                    Pythia.raw_files[fname] = fil.read()
            else:
                print "{} seems to be a directory.".format(f)
                if recurse == False:
                    return "Stopping..."
                elif recurse == True:
                    print "Recursively navingating directory {}".format(f)
                    addFiles(dir,*args)
                else:
                    recurse = raw_input("Recursively navigate through directory {}? (Y/n)".format(f))
                    if recurse[0].lower() == "n":
                        return "Stopping..."
                    else:
                        addFiles(dir,*args)
        else:
            print "Error: file or directory not found at {}".format(f)
    def addFiles(self,directory=None,*args):
        if directory:
            self._recursivelyOpen(directory)
        def argHandler(arg):
            if isinstance(arg,str):
                self._recursivelyOpen(arg)
            elif isinstance(arg,tuple):
                self.addFile(arg[0],arg[1])
            else:
                print "Warning: {} is not a valid argument...skipping..."
                pass
        for arg in args:
            if not isinstance(arg,(str,dict)):
                if len(arg) > 2:
                    for subArg in arg:
                        argHandler(subArg)
                else:
                    argHandler(arg)
            elif isinstance(arg,dict):
                for item in arg.items():
                    argHandler(item)
            else:
                argHandler(arg)
    def _recursivelyOpen(self,f):
        if os.path.isdir(f):
            l = [os.path.join(f,x) for x in os.listdir(f) if x[0] != "."]
            for x in l:
                _recursivelyOpen(x)
        else:
            addFile(f)
4

2 回答 2

2

首先:遵循PEP8的指导方针。模块名、变量名和函数名应该是lowercase_with_underscores; 只有类名应该是CamelCase. 否则,遵循您的代码有点困难。:)

您在这里混淆了 OO 概念:您有一个包含子类实例的父类。

aFileManager主要做 aPythia所做的事情,并进行一些修改或扩展?鉴于两者只能一起工作,我猜不会。

我不太确定你最终希望它是什么样子,但我认为你根本不需要继承。 FileManager可以是它自己的类,self.file_manager在一个Pythia实例上可以是 的一个实例FileManager,然后Pythia可以在必要时委托给它。这与您已经使用此代码的方式相去甚远。

构建小的、独立的部分,然后考虑如何将它们相互连接。


此外,一些错误和风格细节:

  • 你打电话_recursivelyOpen(x)但忘记了self.

  • 逗号后的单个空格。

  • 注意max作为变量名:它也是内置函数的名称。

  • isinstance如果可以,请避免类型检查 ( )。当根据参数类型执行十几种不同的事情时,要遵循您的代码是非常困难的。具有非常清晰的参数类型,并在必要时创建接受不同参数的辅助函数。

  • 你有Pythia.raw_files[fname]inside FileManager,但Pythia它是一个类,它无论如何都没有raw_files属性。

  • 你检查 if recurseis True, then False, then... 别的东西。什么时候是别的东西?此外,您应该使用is而不是==像这样针对内置单例进行测试。

于 2013-02-27T01:16:47.897 回答
0

这里有很多东西,你可能最好对自己进行更多的教育。

对于您的预期用途:

import Pythia
p = Pythia()
p.file_manager.addFile("/path/to/some/file")

像这样的类结构会起作用:

class FileManager(object):
    def __init__(self, parent):
        self.parent = parent

    def addFile(self, file):
        # Your code
        self.parent.raw_files[file] = file

    def addFiles(self, files)
        # Your code
        for file in files:
            self.parent.raw_files[file] = file

class Pythia(object):
    def __init__(self):
        self.file_manager = FileManager(self)

但是有很多选择。您应该首先编写一些客户端代码来确定您想要什么,然后实现您的类/对象以匹配它。我从不倾向于在 python 中使用继承,由于 python 的鸭子类型,它并不是真正需要的。

此外,如果您希望在不实例化类的情况下调用方法,请使用静态方法,而不是类方法。例如:

class FileManager(object):
    @staticmethod
    def addFiles(files):
        pass
于 2013-02-27T01:23:35.547 回答