我正在尝试编写一个类似于内置函数的类,以及我见过的其他一些“成熟”的Python内容。我的Pythonic教育有点不稳定,班级明智,而且我担心我已经把它混淆了。
我想创建一个类作为一种存储库,包含未处理文件的字典(及其名称),以及已处理文件的字典(及其名称)。我想实现一些其他(sub?)类来处理打开和处理文件之类的东西。文件处理类应该能够更新主类中的字典。我还希望能够直接调用各种子模块而无需单独实例化所有内容,例如:
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)
答案 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
属性。
您检查recurse
是True
,然后是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