Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 模块组织、继承和@classmethods_Python_Class_Inheritance - Fatal编程技术网

Python 模块组织、继承和@classmethods

Python 模块组织、继承和@classmethods,python,class,inheritance,Python,Class,Inheritance,我正在尝试编写一个类,它的工作方式有点像内置函数和我见过的其他一些“成熟的”Python东西。我的肾盂疗法教育有点参差不齐,我担心我把它搞混了 我想创建一个类,作为一种存储库,包含未处理文件(及其名称)的字典和已处理文件(及其名称)的字典。我想实现一些其他(子?)类来处理打开和处理文件之类的事情。文件处理类应该能够更新主类中的字典。我还希望能够直接调用各个子模块,而无需单独实例化所有内容,例如: import Pythia p = Pythia() p.FileManager.addFile("

我正在尝试编写一个类,它的工作方式有点像内置函数和我见过的其他一些“成熟的”Python东西。我的肾盂疗法教育有点参差不齐,我担心我把它搞混了

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

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

Pythia.FileManager.addFile("/path/to/some/file")
我一直在看
@classmethod
super
之类的东西,但我不能说我完全理解它。我也开始怀疑,我可能把整个继承链都倒过来了——我认为我的主类实际上应该是处理类和处理类的子类。我还想知道,作为一个软件包,这一切是否会更好,但这是一个单独的、非常可怕的问题

以下是我目前的代码:

#!/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)
首先:遵循公司的指导方针。模块名称、变量名称和函数名称应为带下划线的小写字母;只有类名应该是
CamelCase
。否则,遵循代码有点困难。:)

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

FileManager
是否主要像
Pythia
那样,经过一些修改或扩展?考虑到这两者只在一起工作,我想不会

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

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


此外,还有一些bug和样式错误:

  • 你调用
    \u递归打开(x)
    ,但忘记了
    自身。

  • 逗号后的单个空格

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

  • 如果有帮助,请避免类型检查(
    isinstance
    )。当代码根据参数类型执行十几种不同的操作时,遵循代码就变得格外困难。具有非常清晰的参数类型,并在必要时创建接受不同参数的帮助器函数

  • 您在
    FileManager
    中有
    Pythia.raw_files[fname]
    ,但是
    Pythia
    是一个类,并且它没有
    raw_files
    属性

  • 检查
    递归
    是否为
    ,然后检查
    ,然后。。。还有别的。什么时候有别的事?另外,您应该使用
    is
    而不是
    =
    来测试内置单例,如下所示


这里有很多,你最好多给自己一些教育

对于您的预期用途:

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中使用继承,因为pythons的duck类型并不需要继承

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

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

如果您
导入Pytia
,那是一个模块,而不是一个类。所以你不能做
Pythia()
。您可以在名为
Pythia
的模块中有一个名为
Pythia
的类,在这种情况下,您可以执行
Pythia.Pythia()
。但是你最好通过调用模块
pythia
(正如PEP8所建议的那样)来避免混淆。还有一件事:
self.FileManger=FileManager()
是一个非常糟糕的主意。将一个类和该类的一个实例命名为同一事物肯定会导致混淆。(如果你按照Eevee的建议遵循PEP8,这甚至不会出现-
文件管理器
是通用
文件管理器
实例的合理名称。但是如果你不遵循,你需要一些其他的命名方式,比如苹果风格
文件管理器
)+1,但你仍然没有注意到一个大问题:他正在做
import Pythia
,然后是
Pythia()
。我不确定他是在寻找Pytia的
导入Pytia
来代替第一个还是
Pytia.Pythia()
来代替第二个,你的建议会使区别变得明显,但他仍然需要以一种方式或另一种方式来解决。pff,他就是这样。我认为这只是假设,而不是他尝试运行的实际代码。是的,他说这是他希望能够运行的代码。如果你读到这段话,他似乎在进一步混淆模块和类(例如,将
FileManager
称为子模块),然后试图修补/修改一些东西,却不清楚自己在做什么……我尽量不立即跑到StackOverflow,以免被那些真正知道发生了什么的人弄得面红耳赤。我也应该承认,我没有达到我的政治公众人物标准……我被教导说,camelCase/下划线的区别是个人风格的问题。谢谢你的提醒。这里有一个秘密:我们并不总是知道发生了什么:)十次中有九次,一次