Pregunta

He configurado un script de Python que simula un sistema operativo. Tiene un símbolo del sistema y un sistema de archivos virtuales. Estoy usando el módulo de Shelve para simular el sistema de archivos, siendo multidimensional para admitir una jerarquía de directorios. Sin embargo, tengo problemas para implementar un comando 'CD'. No sé cómo entrar y salir de los directorios, a pesar de que tengo un pequeño conjunto de directorios creados cuando lanza el programa por primera vez. Aquí está mi código:

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...')

No recibo un error, simplemente no tengo idea de cómo hacerlo y no tengo idea de qué buscar además del 'Sistema de archivos Python Shelve', y eso no es nada útil.

¿Fue útil?

Solución

Proporciono un código para ayudarlo a continuación, pero primero, algunos consejos generales que deberían ayudarlo con su diseño:

  • La razón por la que tiene dificultades para cambiar los directorios es que está representando la variable de directorio actual de la manera incorrecta. Su directorio actual debe ser algo así como una lista, desde su directorio de nivel superior hasta el actual. Una vez que tenga eso, simplemente elige cómo almacenar archivos utilizando Shelve en función de su directorio (teniendo en cuenta que todas las claves en Shelve deben ser cadenas).

  • Parece que estaba planeando representar el sistema de archivos como una serie de diccionarios anidados, una buena opción. Pero tenga en cuenta que si cambia objetos mutables en shelve, tiene que a) establecer la reducción de escritura en True y B) llamar a fs.sync () para configurarlos.

  • Debe estructurar todo su sistema de archivos en una clase en lugar de en una serie de funciones. Le ayudará a mantener organizados sus datos compartidos. El siguiente código no sigue eso, pero vale la pena pensar en el que vale la pena.

Entonces, me arreglé cd y también escribió un comando rudimentario Mkdir para ti. Lo crítico para hacer que funcionen es, como dije anteriormente, hacer que actual_dir sea una lista que muestra su ruta actual y también tener una manera fácil (la current_dictionary función) para llegar de esa lista al directorio de sistema de archivos apropiado.

Con eso, aquí está el código para comenzar:

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...')

Y aquí hay una demostración:

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

Es importante tener en cuenta que esto es hasta ahora solo un juguete: Todavía queda mucho por hacer. Aquí están algunos ejemplos:

  • En este momento solo hay tal cosa como directorios, sin archivos regulares.

  • mkdir No verifica si ya existe un directorio, sobrescribiría uno con un directorio vacío.

  • No puedes ls con un directorio específico como argumento (como ls Users), solo su directorio actual.

Aún así, esto debería mostrarle un ejemplo de un diseño para realizar un seguimiento de su directorio actual. ¡Buena suerte!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top