format os.scandir() 输出字符串,添加资源类型

format os.scandir() output string, add resource type

以下代码是在发现阶段产生的,但它的问题从未得到解决,因为当时不需要它。

然而,在重新发现它的问题时,对于更有经验的开发人员来说,这似乎是一个不错的例子,可以作为使用 os.scandir() 进行一项或多项最佳实践教育的起点,'newer',或比 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 的一种方法。代码也更简洁了一些,但是已经 'flattened' 的函数及其调用仍然保留以防万一...

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)

试试这个代码: 你的错误是你的函数return 'None',因为你里面没有return。不要混淆打印和 return.

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

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