Есть ли способ вызвать метод для объекта Python, возвращаемого функцией? - PullRequest
0 голосов
/ 09 июля 2020

Итак, я создаю своего рода учебную программу из командной строки в Python. По сути, он эмулирует терминал и проводит вас по разным уровням с помощью команд оболочки. Исходная версия работала так: я поймал что-то введенное и проанализировал это на предмет вызовов обучающей программы, если их не было, я передал команду компьютеру с помощью os.system ().

К сожалению, поскольку я написал учебник для системы * nix, он не работает на Windows, так как я включил уровни с использованием vim и еще чего-то. Я планировал переписать программу, но вместо того, чтобы делать вызовы системе, я создал виртуальную файловую систему. Сюда входят объекты: каталог и файл. Вероятно, вы сможете понять, чем должны быть оба объекта. Объект каталога будет содержать список своего содержимого, и он будет действовать как файловая система. Затем я бы реализовал такие команды, как cd, ls, pwd и т. Д.

Проблема, с которой я столкнулся, заключается в том, что когда я возвращаю содержащий каталог или файл из объекта каталога, я не могу редактировать любым способом. Я приведу вам пример своего кода.

ПРИМЕЧАНИЕ. В коде, вероятно, есть ошибки, поскольку я не могу хорошо его протестировать, не исправив эту проблему. Кроме того, импорт не требуется для проблемы. Первый - это цветовой класс, который устанавливает коды для цветного вывода, а второй - это файл, содержащий глобальные переменные. Я удалил вызовы этих ресурсов, чтобы он работал в чужой системе

#from ..resources.colors import colors
#from ..resources import variables as var

class Directory:
    # Basic constructor
    def __init__(self, name="", container=None, contents=[]):
        self.name = name
        self.container = container
        self.contents = contents
    
    # grabs index of contents by name
    def index(self, find):
        for i in range(len(self.contents)):
            if self.contents[i].name == find:
                return i
        return -1
    
    # Add something to the container
    def add(self, dirFile):
        # Check for duplicate names
        if self.index(dirFile.name) != -1:
            return False

        self.contents.append(dirFile)
        return True

    # Retrieve something that's in contents
    def get(self, neededName):
        ind = self.index(neededName)
        if ind >= 0:
            return self.contents[ind]

    # Returns true if it has at least one sub directory
    def has_sub(self):
        for content in self.contents:
            if type(content) == Directory:
                return True
        return False
    
    # Iterates through, looks for slashes and goes to subs (recursion, ooooh!)
    def get_sub(self, path=""):
        if not self.has_sub() or path == "":
            return self
        
        pathSplit = path.split("/")
        nextDir = self.index(pathSplit[0])
        
        if nextDir >= 0:
            return self.contents[nextDir]
        
        pathSplit.pop(0)
        path = "/".join(pathSplit)
        return self.get_sub(path)


        
            

    # ============== Shell Commands ==============

    # List all contents in directory
    def ls(self):
        for content in self.contents:
            if type(content) == Directory:
                #print(colors.fg.blue + content.name + colors.reset + "\t", end="") This is the code wih the colors class
                print(content.name + "\t", end="")
            else:
                print(content.name + "\t", end="")
        print()

    # Delete file by name:
    def rm(self, toDelete):
        ind = self.index(toDelete)
        if ind >= 0:
            self.contents.pop(ind)
            return True
        else:
            return False
    
    # Make new dir
    def mkdir(self, name=""):
        if name:
            self.add(Directory(name))
            
        
## Current test
di = Directory("Test")
di.mkdir("one")
di.mkdir("two")

di.get_sub("one").mkdir("test")

di.ls()
di.get_sub("one").ls()

Текущий вывод:

one  two  test
one  two  test

Но вывод должен быть таким:

one two
test

По какой-то причине, когда я звоню:

di.get_sub("one").mkdir("test")

Он меняет di, а не объект, возвращаемый get_sub ()

Любая помощь очень приветствуется! Дайте мне знать, если мне нужно что-нибудь еще.

1 Ответ

1 голос
/ 09 июля 2020

Думаю, я могу вам дать несколько советов. Первое, вероятно, наиболее подходящее, чтобы ответить на ваш основной вопрос:

Он изменяет di, а не объект, возвращаемый get_sub ()

Вероятно, потому что все равно как все работает, has_sub () в конечном итоге преобразуется в подкаталог без дополнительных каталогов. Это приведет к тому, что это предложение станет истинным:

        if not self.has_sub() or path == "":
            return self

if not self.has_sub будет оценивать true и возвращать di. Это всегда будет di, поскольку ваша рекурсивная подпрограмма всегда вызывает методы для self, что равно di. Надеюсь, это имеет смысл!

Что касается второго указателя, который я могу вам дать, возможно, я смогу задать пару вопросов относительно вашего тестового примера, который может помочь в некоторых процессах обнаружения и осознания:

1: di = Directory("Test")
2: di.mkdir("one")
3: di.mkdir("two")

4: di.get_sub("one").mkdir("test")

5: di.ls()
6: di.get_sub("one").ls()
  1. В первой строке вы создаете Test, затем добавляете в (2) и (3) новые (я полагаю) подкаталоги. Однако, глядя на mkdir в вашей реализации Каталога, они на самом деле не создаются. Возможно, посмотрите на os.mkdir и подумайте, нужно ли вам беспокоиться о существующих каталогах. os.path.join тоже может быть вашим другом ...

  2. Хорошо посмотрите, что вы возвращаете. Если вы return self вы возвращаете ссылку на объект, для которого вы вызывали метод. Если вы привяжете второй вызов метода к этому (в вашем случае), он все равно будет di, который вы его вызываете.

Я думаю, вам будет очень весело реализовывать это, если вы сначала начинаете изучать os.path как модуль, тогда рассмотрите некоторые из дополнительных функций ОС, таких как mkdir, упомянутые выше. Также учтите, что os.getcwd () и os.chdir () могут быть интересны.

Я очень надеюсь, что это поможет. : -)

...