2012-01-11 110 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