【问题标题】:Recursion Java vs Python递归 Java 与 Python
【发布时间】:2019-01-17 05:33:50
【问题描述】:

上周我制作了这个 java 文件,想在我的 pc 文件中搜索其中包含我输入的某些单词。 完成之后,我想“为什么不用python翻译它?”在python中我看到它内存不足(因为递归),但在java中没有(在python中,如果我不提供很多目录和文件,代码就可以工作),我在这里放了2个代码和错误(java vs python)所以你可以帮助我(对不起我的英语我不是母语)。

JAVA:

package com.company;

import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;

public class Main {

public static void main(String[] args) {
    System.out.println("Input path to start(remember the / at the end):");
    Scanner input = new Scanner(System.in);
    String path=input.nextLine();
    ArrayList<String> words= new ArrayList<>();
    String word="";
    while(!word.equals("//quit")){
        System.out.println("Input word to search (input://quit to stop):");
        word=input.nextLine();
        if(!word.equals("//quit"))
            words.add(word);
    }
    Finder finder= new Finder(path,castToArray(words));
    finder.readFile();
}

private static void readFiles(Finder finder){
    String[] files = finder.printFiles();
    for(int i=0; i< files.length;i++){
        System.out.println(files[i]);
    }
}

private static String[] castToArray(ArrayList<String> words){
    String[] w0rds = new String[words.size()];
    for(int i=0; i< words.size(); i++){
        w0rds[i]= words.get(i);
    }
    return w0rds;
}

}

class Finder {

private String[] words;
private File file;
private String path;

Finder(String path,String... words){
    this.words=words;
    this.path=path;
    file= new File(path);
}

public String[] printFiles(){
    String[] files;
    files=file.list();
    return files;
}

public void readFile(){
    String[] files= printFiles();
    for(int i=0; i< files.length;i++){
        File f = new File(file.getPath()+"/"+files[i]);
        if(!f.isDirectory()){
            searchWord(f,words);
        }else {
            Finder finder = new Finder(path+f.getName()+"/",words);
            finder.readFile();
        }
    }
}

public File getFile() {
    return file;
}

public void searchWord(File file,String... words){
    DataInputStream dis = null;
    try {
        dis = new DataInputStream(new FileInputStream(file));
        byte[] bytes = new byte[512];
        dis.readFully(bytes);
        String obj = new String(bytes);
        for(int i=0; i< words.length;i++){
            if(obj.contains(words[i])){
                System.out.println(file.getName());
                break;
            }
        }
    } catch (FileNotFoundException e) {
    } catch (IOException e) {
    }

}

}

Python:

import os

class Finder:
    path = ""
    words= []

    def readFile(self,path,words):
        new_file = open(path, "r")
        data=new_file.read(8192)
        new_file.close()
        for word in words:
        if(data.find(word,0,len(data))!=-1):
            print "name: "+new_file.name+" path: "+path
            break

def __init__(self,path, words):
    self.path=path
    self.words=words      

def __del__(self):
    files=os.listdir(path)
    for file in files:
        if(os.path.isdir(path+file)!=True):
            self.readFile(path+file,words)
        else:
            dirpath = path+file+"/"
            finder = Finder(path,words)                            

path= raw_input("input path to start(remember the / at the end):\n")
words=[]
word = ""
while word != "//quit":
    word=raw_input("input word to search (write //quit to start     searching):\n")
    if word != "//quit":
        words.append(word);
print "start searching for "+str(words)+"..."
finder = Finder(path,words)

Python 错误:

Exception RuntimeError: 'maximum recursion depth exceeded' in <bound method Finder.__del__ of <__main__.Finder instance at 0x7f5c0b4f4d40>> ignored
Exception RuntimeError: 'maximum recursion depth exceeded' in <bound method Finder.__del__ of <__main__.Finder instance at 0x7f5c0b4f4c68>> ignored
Exception RuntimeError: 'maximum recursion depth exceeded' in <bound method Finder.__del__ of <__main__.Finder instance at 0x7f5c0b4f4d40>> ignored
Exception RuntimeError: 'maximum recursion depth exceeded' in <bound method Finder.__del__ of <__main__.Finder instance at 0x7f5c0b4f4c68>> ignored

【问题讨论】:

标签: java python file recursion arraylist


【解决方案1】:

您的 python 代码中的问题是,您在 __del__ 中使用全局变量 path 而不是 self.path。因此你会得到一个无限递归。

更好地将您的类转换为函数:

import os

def readFile(path, words):
    with open(path, "r") as new_file:
        data = new_file.read(8192)
    for word in words:
        if word in data:
            print "name: {} path: {}".format(new_file.name, path)
            break

def search(path, words):
    files = os.listdir(path)
    for filename in files:
        fullname = os.path.join(path, filename)
        if not os.path.isdir(fullname):
            readFile(fullname, words)
        else:
            search(fullname, words)

path = raw_input("input path to start: ")
words = []
while True:
    word = raw_input("input word to search (write //quit to start searching): ")
    if word == "//quit":
        break
    words.append(word)
print "start searching for {}...".format(', '.join(words))
search(path, words)

【讨论】:

  • 在使用 del 之前,我使用了您建议的方法,但它给了我同样的错误,谢谢(即使它不起作用)我感谢您的帮助(没有期待有人回答我)
  • 是的,它有效,我只需要添加一个尝试,但效果很好,非常感谢。
【解决方案2】:

在 python 中,您很少应该使用__del__ 方法。它是一种特殊的魔术方法,可以在任意时间(当对象被垃圾收集时)调用,应用程序非常少,并且有多个警告。相反,对于大多数用例,您应该使用显式调用的 .close() 方法或使用上下文管理器(如 contextlib.closing)。

也就是说,我根本不知道您为什么要创建 __del__ 方法,因为在您的 java 代码中没有类似的东西。最接近的 java 方法是 finalize 方法,但您没有使用它,那么为什么在翻译中选择使用 __del__

无论如何,在 python 中,您可以使用 os.walk() 而不是 os.listdir() 来遍历您的目录树 - os.walk() 是迭代递归的,因此它可以处理任何路径深度而不会耗尽调用堆栈空间:

for pth, dirs, files in os.walk(path):
    for filename in files:
        self.readFile(os.path.join(pth, filename))

此代码 sn-p 将调用 readFile 以及所有子文件夹中的所有文件。

【讨论】:

  • 我是 python 的初学者,我看过 del 我觉得“好吧,让我们试试吧”啊哈哈无论如何谢谢我会尝试 walk() 并让你知道。(像“不知道 python 使用 gc”这样的初级水平认为 del 是 c++ 的解构器)
猜你喜欢
  • 2012-08-29
  • 1970-01-01
  • 2013-07-24
  • 1970-01-01
  • 1970-01-01
  • 2013-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多