【问题标题】:format os.scandir() output string, add resource type [closed]格式化 os.scandir() 输出字符串,添加资源类型 [关闭]
【发布时间】:2021-09-25 23:28:14
【问题描述】:

以下代码在发现阶段出现,但其问题从未解决,因为当时不需要。

然而,在重新发现它的问题时,对于更有经验的开发人员来说,这似乎是一个不错的例子,可以用作一个或多个最佳实践的起点,使用 os.scandir(),“更新”或更普遍接受os.listdir() 上的方法。作为以下问题的补充,如果您能解释为什么一个比另一个更受欢迎,或者它们如何互补或不互补,欢迎您提出意见。

一些注释代码仍然存在,显示了在字符串开头插入节点类型的另一种尝试。 while 循环的效果不太好,但它确实起作用了。如何解释它不工作的原因以及应该更换它的替代品,如果有什么比目前使用的功能更流畅,将有助于解决这个问题。

下面列出了我的主要关注点和核心问题,即如何让这个怪物为我开发更精细的 Python 技能。

提前致谢。

import os
import time
basedir = os.path.dirname(__file__)

def scandir_list(basedir):

    entries = os.scandir(basedir)
    # print(entries)
    # <posix.ScandirIterator object at 0x7f5f7d0fe5e0>

    # The ScandirIterator points to all the entries in the current directory.
    # Loop the iterator and print out the content.

    with os.scandir(basedir) as entries:
        for entry in entries:
            def filetype(entry):
                # result = ""
                # while result == "" or result == None:
                print('dir ' if os.path.isdir(entry) else '' , end="")
                print('file ' if os.path.isfile(entry) else '' , end="")
                print('link ' if os.path.islink(entry) else '' , end="")
                print('.. ' if os.path.ismount(entry) else '' , end="")
                    # result = 'dir ' if os.path.isdir(entry) else '' #, end="")
                    # result = 'file ' if os.path.isfile(entry) else '' #, end="")
                    # result = 'link ' if os.path.islink(entry) else ' ' #, end=""
                    # result = '.. ' if os.path.ismount(entry) else ' ' #, end="")
                # print('result: ', result)
                # return result
            resourcetype = filetype(entry)
            size = round(float(os.path.getsize(entry)/1024), 2) # does .2f formatting demonstrate presentation layer bias?
            lastmodified = time.ctime(os.path.getmtime(entry))
            # print(f"{resourcetype}: {entry.name} \t\t\t\t\t Size: {os.path.getsize(entry)/1024:.2f} \t \t \t Last Modified: {time.ctime(os.path.getmtime(entry))}")
            print("{}: Size: {} kb, Last Modified: {}, Name: {}".format(resourcetype, size, lastmodified, entry.name))

scandir_list(basedir)

像这样渲染输出:

file None: Size: 5.76 kb, Last Modified: Sat Sep 25 07:07:28 2021, Name: app.py
dir None: Size: 4.0 kb, Last Modified: Fri Sep 24 23:59:23 2021, Name: test
dir None: Size: 4.0 kb, Last Modified: Sat Sep 25 04:15:51 2021, Name: views

问题:

(为了清楚起见,这里的代码是关于测试限制的,所以该方法可能只是呈现错误的开始方式......)

1.) 因为资源名称是可变长度的,并且插入到字符串格式中的制表符 (\t) 是相对的(没有停止),所以资源名称已附加到末尾。期望的结果是将资源名称放在第二个槽中。如何将资源名称放入第二个槽中,并以最少的代码对字符串进行格式化以避免锯齿状边缘——无论重构在重组方面需要什么,还是采用完全不同的方法?

2.) 第一个槽,资源名称,带有 None,但原因(其他打印语句内联到字符串的形成)尚不清楚。您的解释和解决方法是什么?

更新:

最初呈现的代码是完整的,因为它有大量的注释语句,主要是为了重构替代项。

下面是摆脱None 的一种方法。代码也更简洁一些,但已经“扁平化”的函数及其调用仍然存在,以防万一......

import os
import time
basedir = os.path.dirname(__file__)

def scandir_list(basedir):
    with os.scandir(basedir) as entries:
        for entry in entries:
            resdict = dict()
            resdict.update({'res': 'dir'}) if entry.is_dir() else ''
            resdict.update({'res': 'file'}) if entry.is_file() else ''
            resdict.update({'res': 'link'}) if entry.is_symlink() else ''
            # resdict.update({'res': '..'}) if os.path.ismount(entry) else ''
            resourcetype = resdict['res']
            # print("resdict: ", resdict) # what's it look like?
            size = round(float(os.path.getsize(entry)/1024), 2)
            lastmodified = time.ctime(os.path.getmtime(entry))
            print("{}: Size: {} kb, Last Modified: {}, Name: {}".format(resourcetype, size, lastmodified, entry.name))
            # del resdict # not really necessary

if __name__ == "__main__":
    scandir_list(basedir)

【问题讨论】:

  • 为什么要定义一个在循环内不会改变的函数?为什么你的代码中有这么多注释打印行?你想拥有什么?您能否提供预期结果的示例以便我们提供帮助?请用更多合成句子重新格式化问题......(你有 None 因为你的函数没有返回,它被评论了)
  • @VincentBénet 真是一团糟。这是一种快速而肮脏的方法,确实没有用,而且,正如您的问题所示,最初没有经过深思熟虑。希望这会改变。使用 dict.update() 的更新替换了打印语句。回报并没有像以前那样拼凑而成。现在它正在格式化,也许是已知类型的条件显示。格式化让我很困惑。关于选项卡 (\t) 或替代选项的任何想法?
  • 嗨,我只是修改我的答案以在返回字符串中插入 \t 以便在列中格式化。 (请注意,它仅防止 4 位数的移位线。使用字符串切片来防止这种情况。

标签: python scandir directory-listing


【解决方案1】:

试试这个代码: 您的错误是您的函数返回“无”,因为您没有返回。不要混淆打印和退货。

请在下面找到您的代码以及最佳实践:

import os
import time


def scandir_list(dir_path):
    result = ""
    for entry in os.scandir(dir_path):
        stats = entry.stat()
        result += f"""{
                (
                    [
                        filetype 
                        for filetype in ['dir', 'file', 'mount', 'link'] 
                        if getattr(os.path, f"is{filetype}")(entry)
                    ] + 
                    ["Unknow"]
                )[0]
            }\tSize: {
                round(float(os.path.getsize(entry)/1024), 2)
            }kb\tLast Modified: {
                time.ctime(stats.st_mtime)
            }\tName: {entry.name}\n"""
    return result


if __name__ == "__main__":
    print(scandir_list(os.path.dirname(__file__)))

这是我的输出:

dir     Size: 16.0kb  Last Modified: Fri Sep 24 10:17:24 2021     Name: xxx
dir     Size: 28.0kb  Last Modified: Tue Sep  7 12:15:40 2021     Name: yyy
dir     Size: 4.0kb   Last Modified: Fri Sep 24 11:00:04 2021     Name: zzz
dir     Size: 28.0kb  Last Modified: Tue Jun 15 22:16:15 2021     Name: aaa
dir     Size: 4.0kb   Last Modified: Thu Mar 18 14:54:12 2021     Name: bbb
dir     Size: 4.0kb   Last Modified: Tue Jul 28 22:12:35 2020     Name: ccc
file    Size: 2.22kb  Last Modified: Thu Jul 22 15:44:15 2021     Name: ddd.py

【讨论】:

  • 更简洁的代码,文森特。在我的最后,计算出遍历各种类型的部分,因为这将返回一个类型为 class ` 的字符串。在我看来,被标记在字符串末尾的资源名称在美学上并不令人愉悦。这是一种解决方法。关于使其成为字符串中显示的第二个值的任何想法 - 没有以下字段的锯齿状边缘?
  • 代码已编辑,请重试,它将按需要运行。如果您觉得可以,请用绿色标记
  • def filetype(entry): for filetype in ['dir', 'file', 'mount', 'link']: if getattr(os.path, f"is{filetype}")(entry): return filetype else: return "Unknow" 是的,可以完美地将返回从“类型”更改为“文件类型”。变量 'path' 名称更改为 'entry' 以更好地反映正在传递的变量,并避免与 'os.path' 发生冲突(仅限感知)。更简单(和复杂)的代码。谢谢。
  • Benet 经过一些跟进和一些意外发现,在我看来,答案对 scandir() 的功能,尤其是 DirEntry 的功能并不公平,正如 scandir() @987654321 所揭示的那样@。调用 os.path.isfile(basepath) 等,避免使用 scandir 的包含类型,导致对操作系统的调用在代码中累积,这是编写 PEP 覆盖 scandir 并被接受为针对标准库。 benhoyt.com/writings/scandir
  • 是的,请访问此链接:docs.python.org/3/library/os.html#os.stat_result 看看方法:entry.stat()。我的代码已被修改以在此文档上显示时间
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-02
  • 1970-01-01
相关资源
最近更新 更多