模块组织,继承和@classmethods

时间:2013-02-27 01:03:34

标签: python class inheritance

我正在尝试编写一个类似于内置函数的类,以及我见过的其他一些“成熟”的Python内容。我的Pythonic教育有点不稳定,班级明智,而且我担心我已经把它混淆了。

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

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)

2 个答案:

答案 0 :(得分:2)

首先关注:遵循PEP8的指导原则。模块名称,变量名称和函数名称应为lowercase_with_underscores;只有班级名称应为CamelCase。遵循您的代码有点困难。 :)

你在这里弄乱了OO概念:你有一个包含子类实例的父类。

FileManager主要通过Pythia做什么,做一些修改或扩展?鉴于两者只能一起工作,我猜不会。

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

构建小的,独立的部分,然后担心如何将它们相互插入。


此外,还有一些错误和风格:

  • 您致电_recursivelyOpen(x)但忘了self.

  • 逗号后的单个空格。

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

  • 如果可以提供帮助,请避免使用类型检查(isinstance)。根据参数类型执行十几种不同的操作时,遵循代码会非常困难。有非常明确的参数类型,并创建辅助函数,必要时接受不同的参数。

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

    < / LI>
  • 您检查recurseTrue,然后是False,然后是......别的。什么时候还别的?另外,您应该使用is代替==来测试这样的内置单例。

答案 1 :(得分: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中使用继承,由于蟒蛇打字,它并不是真正需要的。

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

class FileManager(object):
    @staticmethod
    def addFiles(files):
        pass