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。それ以外の場合、コードに従うのは少し難しいです。:)

ここでオブジェクト指向の概念を混乱させています。サブクラスのインスタンスを含む親クラスがあります。

aは、いくつかの変更または拡張を加えて、FileManagerほとんどaが行うことを行いますか? Pythiaこの2つが一緒にしか機能しないことを考えると、そうではないと思います。

最終的にこれをどのようにしたいのかよくわかりませんが、継承はまったく必要ないと思います。 FileManagerは独自のクラスにすることができ、インスタンスself.file_manager上は のインスタンスにすることができ、必要に応じて委任することができます。これは、このコードを既に使用している方法からそれほど遠くありません。PythiaFileManagerPythia

小さな独立したピースを構築し、それらを互いに接続する方法を考えます。


また、いくつかのバグとスタイルニット:

  • あなたは電話をかけ_recursivelyOpen(x)ましたが、を忘れましたself.

  • カンマの後のシングル スペース。

  • 変数名として注意してmaxください。これは組み込み関数の名前でもあります。

  • isinstance可能な場合は、型チェック ( ) を避けてください。引数の型に応じてさまざまなことを行う場合、コードをたどるのは非常に困難です。非常に明確な引数の型を持ち、必要に応じて異なる引数を受け入れるヘルパー関数を作成します。

  • Pythia.raw_files[fname]内部FileManagerに がありますが、これはクラスであり、属性Pythiaはありません。raw_files

  • recurseが であるかどうかを確認し、True次にFalse... 他の何かを確認します。それ以外はいつですか?また、このような組み込みシングルトンに対するテストの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のダックタイピングのため、継承は実際には必要ありません。

また、クラスをインスタンス化せずにメソッドを呼び出す場合は、classmethodではなくstaticmethodを使用します。例えば:

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