2012-01-11 114 views
5

我已经设置了一个模拟OS的Python脚本。它有一个命令提示符和一个虚拟文件系统。我正在使用搁置模块来模拟文件系统,它是多维的,以支持目录层次结构。但是,我无法执行'cd'命令。我不知道如何进入和退出目录,即使我在第一次启动程序时创建了一小组目录。这里是我的代码:如何使用shelve实现Python虚拟文件系统

import shelve 

fs = shelve.open('filesystem.fs') 
directory = 'root' 
raw_dir = None 
est_dir = None 

def install(fs): 
    fs['System'] = {} 
    fs['Users'] = {} 
    username = raw_input('What do you want your username to be? ') 
    fs['Users'][username] = {} 

try: 
    test = fs['runbefore'] 
    del test 
except: 
    fs['runbefore'] = None 
    install(fs) 

def ls(args): 
    print 'Contents of directory', directory + ':' 
    if raw_dir: 
     for i in fs[raw_dir[0]][raw_dir[1]][raw_dir[2]][raw_dir[3]]: 
      print i 
    else: 
     for i in fs: 
      print i 

def cd(args): 
    if len(args.split()) > 1: 
     if args.split()[1] == '..': 
      if raw_dir[3]: 
       raw_dir[3] = 0 
      elif raw_dir[2]: 
       raw_dir[2] = 0 
      elif raw_dir[1]: 
       raw_dir[1] = 0 
      else: 
       print "cd : cannot go above root" 

COMMANDS = {'ls' : ls} 

while True: 
    raw = raw_input('> ') 
    cmd = raw.split()[0] 
    if cmd in COMMANDS: 
     COMMANDS[cmd](raw) 

#Use break instead of exit, so you will get to this point. 
raw_input('Press the Enter key to shutdown...') 

我没有得到一个错误,我只是不知道如何做到这一点并没有什么搜索除了“蟒蛇货架文件系统”的想法,而且不得到有用的东西。

+1

有趣!你介意分享这是为了什么吗? – 2012-01-11 03:43:08

+0

我设置了你的代码在我的Eclipse中为python3.x工作...现在就玩它。到目前为止,我有点困惑。但没关系。正如大卫所说,你能提供一些背景吗? – Bry6n 2012-01-11 03:57:34

+0

这是我可以试试看。只是为了好玩。 – elijaheac 2012-01-11 22:25:30

回答

7

我提供一些代码来帮助你在下面,但首先,一些整体建议,应可帮助您进行设计:

  • 您有任何关于更改目录困难的原因是,你是代表当前目录变量的方式是错误的。您的当前目录应该像列表一样,从顶级目录到当前目录。一旦你有了这些,你就可以根据他们的目录选择使用搁置文件来存储文件(考虑到Shelve中的所有密钥都必须是字符串)。

  • 它看起来像你打算将文件系统表示为一系列嵌套字典 - 一个不错的选择。但请注意,如果更改shelve中的可变对象,则必须a)将写回设置为True,并b)调用fs.sync()来设置它们。

  • 你应该在一个类中构建整个文件系统,而不是一系列的功能。它将帮助你保持你的共享数据的组织。下面的代码并不遵循这一点,但值得思考。

所以,我搞掂cd也写了一个基本的mkdir命令你。使它们工作的关键是,正如我上面所说的,current_dir是一个显示当前路径的列表,并且还有一个简单的方法(current_dictionary函数)从列表中获取到相应的文件系统目录。

就这样,这里的代码,让你开始:

import shelve 

fs = shelve.open('filesystem.fs', writeback=True) 
current_dir = [] 

def install(fs): 
    # create root and others 
    username = raw_input('What do you want your username to be? ') 

    fs[""] = {"System": {}, "Users": {username: {}}} 

def current_dictionary(): 
    """Return a dictionary representing the files in the current directory""" 
    d = fs[""] 
    for key in current_dir: 
     d = d[key] 
    return d 

def ls(args): 
    print 'Contents of directory', "/" + "/".join(current_dir) + ':' 
    for i in current_dictionary(): 
     print i 

def cd(args): 
    if len(args) != 1: 
     print "Usage: cd <directory>" 
     return 

    if args[0] == "..": 
     if len(current_dir) == 0: 
      print "Cannot go above root" 
     else: 
      current_dir.pop() 
    elif args[0] not in current_dictionary(): 
     print "Directory " + args[0] + " not found" 
    else: 
     current_dir.append(args[0]) 


def mkdir(args): 
    if len(args) != 1: 
     print "Usage: mkdir <directory>" 
     return 
    # create an empty directory there and sync back to shelve dictionary! 
    d = current_dictionary()[args[0]] = {} 
    fs.sync() 

COMMANDS = {'ls' : ls, 'cd': cd, 'mkdir': mkdir} 

install(fs) 

while True: 
    raw = raw_input('> ') 
    cmd = raw.split()[0] 
    if cmd in COMMANDS: 
     COMMANDS[cmd](raw.split()[1:]) 

#Use break instead of exit, so you will get to this point. 
raw_input('Press the Enter key to shutdown...') 

而这里的一个示范:

What do you want your username to be? David 
> ls 
Contents of directory /: 
System 
Users 
> cd Users 
> ls 
Contents of directory /Users: 
David 
> cd David 
> ls 
Contents of directory /Users/David: 
> cd .. 
> ls 
Contents of directory /Users: 
David 
> cd .. 
> mkdir Other 
> ls 
Contents of directory /: 
System 
Users 
Other 
> cd Other 
> ls 
Contents of directory /Other: 
> mkdir WithinOther 
> ls 
Contents of directory /Other: 
WithinOther 

重要的是要注意,这是迄今为止只是一个玩具是很重要的:有还剩下一吨做。这里有几个例子:

  • 现在只有目录 - 没有常规文件这样的事情。

  • mkdir不检查一个目录是否已经存在,它会覆盖一个空目录。

  • 您不能将ls作为参数(如ls Users),只有您的当前目录。

不过,这应该会显示一个跟踪当前目录的设计示例。祝你好运!

+1

你在第35行有一个小错误。应该是'print'目录/“+'/'.join(current_dir)+”not found“'。现在它的添加字符串和列表 – jdi 2012-01-11 04:46:35

+0

哎呀。它实际上应该是没有找到的args [0](这当然是一个字符串)。谢谢 – 2012-01-11 04:48:22

+1

不错的工作。我实际上正在同时研究这个问题,并提出了几乎相同的方法:-)我只是让'cd'命令即时创建空目录。但是关于回写属性 – jdi 2012-01-11 04:51:44