简体   繁体   English

有没有办法在 function 返回的 Python object 上调用方法?

[英]Is there a way to call a method on a Python object returned by a function?

So I'm building a command-line tutorial program of sorts in Python.所以我正在 Python 中构建一个命令行教程程序。 Basically it emulates a terminal and walks you through different levels using shell commands.基本上它模拟一个终端并使用 shell 命令引导您完成不同的级别。 The way the original version worked is I caught anything entered and analyzed it for calls to the tutorial program if there weren't any I passed the command to the computer using os.system().原始版本的工作方式是我捕获输入的任何内容并分析它以调用教程程序(如果没有任何内容)我使用 os.system() 将命令传递给计算机。

Unfortunately, since I wrote the tutorial to be of a *nix system, it does not work on Windows, since I included levels using vim and what-not.不幸的是,由于我编写的教程是针对 *nix 系统的,因此它不适用于 Windows,因为我包含了使用 vim 之类的关卡。 My plan was to rewrite the program, but rather than making calls to the system, I'd create a virtual filesystem.我的计划是重写程序,但不是调用系统,而是创建一个虚拟文件系统。 This includes to objects: directory and file.这包括对象:目录和文件。 You can probably figure out what both of the objects are meant to be.您可能会弄清楚这两个对象的含义。 The directory object would contain a list of its contents and this would act as the filesystem.目录 object 将包含其内容列表,这将充当文件系统。 I would then implement commands like cd, ls, pwd, and so-on.然后,我将执行 cd、ls、pwd 等命令。

The problem I have run in to is that when I return a containing directory or file from a directory object I'm not able to edit it in any way.我遇到的问题是,当我从目录 object 返回包含目录或文件时,我无法以任何方式对其进行编辑。 I'll give you an example of my code.我会给你一个我的代码的例子。

NOTE: There are likely bugs in the code as I cannot test it very well without fixing this issue Also, the imports aren't necessary to the problems.注意:代码中可能存在错误,因为如果不解决此问题,我无法很好地测试它此外,导入对于问题来说不是必需的。 The first one is a color class that lays out the codes for doing colored output and the second is a file that contains global variables.第一个是颜色 class ,它列出了执行彩色 output 的代码,第二个是包含全局变量的文件。 I've removed the calls to these resources so that it will run on someone else's system我已经删除了对这些资源的调用,以便它可以在其他人的系统上运行

#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()

The current output is:当前的output为:

one  two  test
one  two  test

But the output should read:但是 output 应该是:

one two
test

For some reason when I call:出于某种原因,当我打电话时:

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

It changes di rather than the object returned by get_sub()它改变了 di 而不是 get_sub() 返回的 object

Any help is much appreaciated.任何帮助都非常感谢。 Let me know if there's anything else I should provide.让我知道是否还有其他我应该提供的东西。

There are a couple of pointers I think I can give you.我想我可以给你一些建议。 The first is, probably most appropriately, to answer your primary question:第一个可能最合适的是回答您的主要问题:

It changes di rather than the object returned by get_sub()它改变了 di 而不是 get_sub() 返回的 object

This is likely because no matter how things work out, has_sub() will eventually resolve to a subdirectory with no further directories in. This will result in this clause becoming true:这很可能是因为无论事情如何发展,has_sub() 最终都会解析到一个没有其他目录的子目录。这将导致该子句变为 true:

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

if not self.has_sub will evaluate true and return di . if not self.has_sub将评估 true 并返回di It'll always be di as your recursive routine always calls methods on self which is di .它总是di因为你的递归例程总是调用self上的方法,即di I hope that makes sense!我希望这是有道理的!

In terms of the second pointer I can give you, maybe I can ask a couple of questions regarding your test-case which might assist with some discover and though processes:关于我可以给你的第二个指针,也许我可以问几个关于你的测试用例的问题,这可能有助于一些发现和通过过程:

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. In line one you create Test , then add in (2) and (3) new (I suppose) subdirectories.在第一行创建Test ,然后添加 (2) 和 (3) 新的(我想)子目录。 However, looking at mkdir in your Directory implementation, these don't actually get created.但是,在您的 Directory 实现中查看 mkdir ,这些实际上并没有被创建。 Perhaps look at os.mkdir and consider whether you need to worry about existing directories.也许看看os.mkdir并考虑您是否需要担心现有目录。 os.path.join might also be your friend here... os.path.join也可能是你的朋友......

  2. Have a good look at what you're returning.好好看看你要返回的东西。 If you return self you're returning the reference to the object you called the method on.如果您return self您将返回对您调用该方法的 object 的引用。 If you chain a second method call to that (in your case) it will still be di that you call it on.如果你将第二个方法调用链接到那个(在你的情况下)它仍然是你调用它的di

I think you'll have a lot of fun implementing this if you first start looking first looking into os.path as a module then consider some of the additional os functions like mkdir mentioned above.我认为,如果您首先开始研究os.path作为一个模块,然后考虑一些附加的 os 函数,例如上面提到的 mkdir,那么您将获得很多乐趣。 Also consider that os.getcwd() and os.chdir() might be of interest.还要考虑到os.getcwd()os.chdir()可能很有趣。

I really hope this helps.我真的希望这会有所帮助。 :-) :-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM