Hướng dẫn python scandir - trăn để leo lên

Tác giả: Ben Hoyt BDFL-Delegate: Victor Stinner Tình trạng: FinalType: Tiêu chuẩn theo dõi: 30-tháng 5 năm 2014PyThon-Vers:Ben Hoyt BDFL-Delegate:Victor Stinner Status:FinalType:Standards TrackCreated:30-May-2014Python-Version:3.5Post-History:27-Jun-2014, 08-Jul-2014, 14-Jul-2014
Mục lục
  • trừu tượng
  • Cơ sở lý luận
  • Thực hiện
  • Cụ thể của đề xuất
    • os.scandir()
    • os.walk()
  • Ví dụ
    • Ghi chú về bộ nhớ đệm
    • Ghi chú về xử lý ngoại lệ
  • Ủng hộ
  • Sử dụng trong tự nhiên
  • Từ chối ý tưởng
    • Đặt tên
    • người hỗ trợ ký đại diện
    • Các phương thức không theo dõi các liên kết symlink theo mặc định
    • Thuộc tính direntry là thuộc tính
    • Các trường Direntry là các đối tượng chỉ thuộc tính thuộc tính tĩnh
    • Các trường Direntry đang tĩnh với tùy chọn đảm bảo_lstat
    • Trả về các giá trị là (tên, stat_result) hai bộ phận
    • Trả về các giá trị bị quá tải các đối tượng Stat_Result
    • Trả về các giá trị là các đối tượng pathlib.path
  • Có thể cải thiện
  • Thảo luận trước
  • Bản quyền

trừu tượng

PEP này đề xuất bao gồm một chức năng lặp thư mục mới, os.scandir(), trong thư viện tiêu chuẩn. Chức năng mới này thêm chức năng hữu ích và tăng tốc độ os.walk() lên 2-20 lần (tùy thuộc vào nền tảng và hệ thống tệp) bằng cách tránh các cuộc gọi đến os.stat() trong hầu hết các trường hợp.

Cơ sở lý luận

Thực hiện

Cụ thể của đề xuất

Ví dụ

Ghi chú về bộ nhớ đệm8-9 times as fast on Windows, and about 2-3 times as fast on POSIX systems. So we’re not talking about micro- optimizations. See more benchmarks here.

Ghi chú về xử lý ngoại lệ

Ủng hộ

Thực hiện

Cụ thể của đề xuất

Ví dụ

Cụ thể của đề xuất

os.scandir()

Ví dụ

scandir(path='.') -> generator of DirEntry objects

Ghi chú về bộ nhớ đệm

  • Ghi chú về xử lý ngoại lệ
  • Ủng hộ

Sử dụng trong tự nhiên

  • Từ chối ý tưởng
  • Đặt tên
  • người hỗ trợ ký đại diện
  • it = os.scandir(path)
    while True:
        try:
            entry = next(it)
        except OSError as error:
            handle_error(path, error)
        except StopIteration:
            break
    
    5: Tương tự như
    it = os.scandir(path)
    while True:
        try:
            entry = next(it)
        except OSError as error:
            handle_error(path, error)
        except StopIteration:
            break
    
    6, nhưng giá trị trả về được lưu trong bộ đệm trên đối tượng
    def get_tree_size(path):
        """Return total size of files in given path and subdirs."""
        total = 0
        for entry in os.scandir(path):
            if entry.is_dir(follow_symlinks=False):
                total += get_tree_size(entry.path)
            else:
                total += entry.stat(follow_symlinks=False).st_size
        return total
    
    8; Không yêu cầu một cuộc gọi hệ thống trong hầu hết các trường hợp; Don Tiết theo các liên kết tượng trưng nếu
    it = os.scandir(path)
    while True:
        try:
            entry = next(it)
        except OSError as error:
            handle_error(path, error)
        except StopIteration:
            break
    
    8 là sai
  • it = os.scandir(path)
    while True:
        try:
            entry = next(it)
        except OSError as error:
            handle_error(path, error)
        except StopIteration:
            break
    
    9: Tương tự như os.scandir()0, nhưng giá trị trả về được lưu trong bộ đệm trên đối tượng
    def get_tree_size(path):
        """Return total size of files in given path and subdirs."""
        total = 0
        for entry in os.scandir(path):
            if entry.is_dir(follow_symlinks=False):
                total += get_tree_size(entry.path)
            else:
                total += entry.stat(follow_symlinks=False).st_size
        return total
    
    8; Không yêu cầu một cuộc gọi hệ thống trong hầu hết các trường hợp; Don Tiết theo các liên kết tượng trưng nếu
    it = os.scandir(path)
    while True:
        try:
            entry = next(it)
        except OSError as error:
            handle_error(path, error)
        except StopIteration:
            break
    
    8 là sai
  • os.scandir()3: Tương tự như os.scandir()4, nhưng giá trị trả về được lưu trong bộ đệm trên đối tượng
    def get_tree_size(path):
        """Return total size of files in given path and subdirs."""
        total = 0
        for entry in os.scandir(path):
            if entry.is_dir(follow_symlinks=False):
                total += get_tree_size(entry.path)
            else:
                total += entry.stat(follow_symlinks=False).st_size
        return total
    
    8; không yêu cầu một cuộc gọi hệ thống trong hầu hết các trường hợp
  • os.scandir()6: Giống như os.stat(), nhưng giá trị trả về được lưu trong bộ đệm trên đối tượng
    def get_tree_size(path):
        """Return total size of files in given path and subdirs."""
        total = 0
        for entry in os.scandir(path):
            if entry.is_dir(follow_symlinks=False):
                total += get_tree_size(entry.path)
            else:
                total += entry.stat(follow_symlinks=False).st_size
        return total
    
    8; không yêu cầu gọi hệ thống trên Windows (ngoại trừ Symlinks); Don Tiết theo các liên kết tượng trưng (như os.scandir()9) nếu
    it = os.scandir(path)
    while True:
        try:
            entry = next(it)
        except OSError as error:
            handle_error(path, error)
        except StopIteration:
            break
    
    8 là sai

Tất cả các phương thức có thể thực hiện các cuộc gọi hệ thống trong một số trường hợp và do đó có thể tăng os.walk()1 - xem phần Ghi chú trên phần Xử lý ngoại lệ để biết thêm chi tiết.

Thuộc tính

def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total
8 tên phương thức được chọn giống như các thuộc tính trong mô -đun os.walk()3 mới nếu có thể, cho tính nhất quán. Sự khác biệt duy nhất về chức năng là các phương thức
def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total
8 đã lưu trữ các giá trị của chúng trên đối tượng nhập sau cuộc gọi đầu tiên.

Giống như các hàm khác trong mô -đun

def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total
2,
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
9 chấp nhận một đối tượng byte hoặc STR cho tham số
def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total
6 và trả về các thuộc tính os.walk()8 và os.walk()9 có cùng loại với
def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total
6. Tuy nhiên, bạn nên sử dụng loại STR, vì điều này đảm bảo hỗ trợ đa nền tảng cho tên tệp unicode. .

os.walk()

Là một phần của đề xuất này, os.walk() cũng sẽ được sửa đổi để sử dụng

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
9 thay vì os.stat()3 và os.stat()4. Điều này sẽ tăng tốc độ os.walk() rất đáng kể (như đã đề cập ở trên, bằng 2-20 lần, tùy thuộc vào hệ thống).

Ví dụ

Đầu tiên, một ví dụ rất đơn giản về

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
9 hiển thị việc sử dụng thuộc tính os.walk()8 và phương thức os.stat()8:

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name

Hàm os.stat()9 này sẽ nhanh hơn đáng kể với scandir so với os.listdir()os.stat()4 trên cả hệ thống Windows và Posix, đặc biệt là trên các thư mục cỡ trung bình hoặc lớn.

Hoặc, để có được tổng kích thước của các tệp trong một cây thư mục, hiển thị việc sử dụng phương thức os.walk()2 và thuộc tính os.walk()9:

def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total

Điều này cũng cho thấy việc sử dụng tham số

it = os.scandir(path)
while True:
    try:
        entry = next(it)
    except OSError as error:
        handle_error(path, error)
    except StopIteration:
        break
8 thành os.walk()5 - trong một hàm đệ quy như thế này, có lẽ chúng ta không muốn theo các liên kết. .

Lưu ý rằng os.walk()6 sẽ tăng tốc độ tăng tốc độ lớn trên Windows, vì không cần cuộc gọi chỉ số bổ sung, nhưng trên các hệ thống POSIX, thông tin kích thước không được trả về bởi các chức năng lặp thư mục, vì vậy chức năng này đã giành được bất cứ thứ gì ở đó.

Ghi chú về bộ nhớ đệm

Các đối tượng

def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total
8 tương đối ngu ngốc - các thuộc tính
def get_tree_size(path):
    """Return total size of files in path and subdirs. If
    is_dir() or stat() fails, print an error message to stderr
    and assume zero size (for example, file has been deleted).
    """
    total = 0
    for entry in os.scandir(path):
        try:
            is_dir = entry.is_dir(follow_symlinks=False)
        except OSError as error:
            print('Error calling is_dir():', error, file=sys.stderr)
            continue
        if is_dir:
            total += get_tree_size(entry.path)
        else:
            try:
                total += entry.stat(follow_symlinks=False).st_size
            except OSError as error:
                print('Error calling stat():', error, file=sys.stderr)
    return total
7 và
def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total
6 rõ ràng luôn được lưu trữ và các phương thức os.listdir()0 và os.listdir()1 lưu trữ các giá trị của chúng (ngay lập tức trên Windows thông qua hệ thống.

Vì lý do này, các đối tượng

def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total
8 được dự định sẽ được sử dụng và vứt bỏ sau khi lặp lại, không được lưu trữ trong dữ liệu tồn tại lâu dài được cấu trúc và các phương thức được gọi hết lần này đến lần khác.

Nếu các nhà phát triển muốn hành vi làm mới của người Viking (ví dụ, để xem thay đổi kích thước tệp), họ chỉ có thể sử dụng các đối tượng os.listdir()5 hoặc gọi các hàm os.stat() hoặc os.listdir()7 thông thường nhận được dữ liệu mới từ hệ điều hành mỗi cuộc gọi.

Ghi chú về xử lý ngoại lệ

os.listdir()8 và os.walk()2 là các phương thức rõ ràng thay vì các thuộc tính hoặc thuộc tính, để làm rõ rằng chúng có thể không phải là hoạt động rẻ tiền (mặc dù chúng thường là như vậy) và chúng có thể thực hiện một cuộc gọi hệ thống. Do đó, các phương pháp này có thể tăng os.walk()1.

Ví dụ, os.walk()2 sẽ luôn thực hiện cuộc gọi hệ thống trên các hệ thống dựa trên POSIX và các phương thức os.listdir()8 sẽ thực hiện cuộc gọi hệ thống

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
0 trên các hệ thống đó nếu
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
04 không hỗ trợ
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
05 hoặc trả về
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
05 với giá trị
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
07 điều kiện hoặc trên một số hệ thống tập tin.

Thông thường, điều này không quan trọng - ví dụ, os.walk() như được định nghĩa trong thư viện tiêu chuẩn chỉ bắt các lỗi xung quanh các cuộc gọi os.stat()3.

Ngoài ra, bởi vì hành vi gây ra ngoại lệ của các phương pháp

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
10 phù hợp với os.walk()3-chỉ tăng os.walk()1 trong trường hợp quyền hoặc các lỗi gây tử vong khác, nhưng trả về sai nếu đường dẫn không tồn tại cần thiết để bắt lỗi xung quanh các cuộc gọi
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
13.

Tuy nhiên, khi người dùng yêu cầu xử lý lỗi hạt mịn, có thể mong muốn bắt os.walk()1 xung quanh tất cả các cuộc gọi phương thức và xử lý khi thích hợp.

Ví dụ: bên dưới là phiên bản của ví dụ os.walk()6 được hiển thị ở trên, nhưng với xử lý lỗi hạt mịn được thêm vào:

def get_tree_size(path):
    """Return total size of files in path and subdirs. If
    is_dir() or stat() fails, print an error message to stderr
    and assume zero size (for example, file has been deleted).
    """
    total = 0
    for entry in os.scandir(path):
        try:
            is_dir = entry.is_dir(follow_symlinks=False)
        except OSError as error:
            print('Error calling is_dir():', error, file=sys.stderr)
            continue
        if is_dir:
            total += get_tree_size(entry.path)
        else:
            try:
                total += entry.stat(follow_symlinks=False).st_size
            except OSError as error:
                print('Error calling stat():', error, file=sys.stderr)
    return total

Ủng hộ

Mô-đun Scandir trên GitHub đã được đưa ra và được sử dụng khá nhiều (xem sử dụng trên mạng hoang dã trong PEP này), nhưng cũng có một chút hỗ trợ trực tiếp cho chức năng giống như scandir từ các nhà phát triển cốt lõi và những người khác trên Python -Dev và Python-Ideas Danh sách gửi thư. Một mẫu:

  • Python-dev: Một số lượng tốt +1 1 và rất ít tiêu cực cho scandir và pep 471 trên chủ đề Python-dev tháng 6 năm 2014 này: a good number of +1’s and very few negatives for scandir and PEP 471 on this June 2014 python-dev thread
  • Nick Coghlan, một nhà phát triển Python cốt lõi: Tôi đã có nhóm Kỹ thuật phát hành Hat Hat địa phương thể hiện sự không hài lòng của họ khi phải thống kê mọi tệp trong một cây thư mục gắn kết mạng để biết thông tin trong cấu trúc Dirent, do đó đến Os.Scandir từ tôi, miễn là nó có sẵn thông tin đó. [Nguồn1], a core Python developer: “I’ve had the local Red Hat release engineering team express their displeasure at having to stat every file in a network mounted directory tree for info that is present in the dirent structure, so a definite +1 to os.scandir from me, so long as it makes that info available.” [source1]
  • Tim Golden, một nhà phát triển Python cốt lõi, hỗ trợ Scandir đủ để dành thời gian tái cấu trúc và cải thiện đáng kể mô -đun mở rộng Scandir. [Nguồn2], a core Python developer, supports scandir enough to have spent time refactoring and significantly improving scandir’s C extension module. [source2]
  • Christian Heimes, một nhà phát triển Python cốt lõi: Hồi +1 cho một cái gì đó như whiteddir () [[Source3] và thực sự! Tôi muốn xem tính năng này trong 3,4 để tôi có thể loại bỏ bản hack của riêng mình khỏi cơ sở mã của chúng tôi. [Nguồn4], a core Python developer: “+1 for something like yielddir()” [source3] and “Indeed! I’d like to see the feature in 3.4 so I can remove my own hack from our code base.” [source4]
  • Gregory P. Smith, một nhà phát triển Python cốt lõi: Từ 3.4beta1 xảy ra tối nay, đây không phải là 3,4 vì vậy tôi đã tăng tốc độ này lên 3,5. Tôi thực sự thích thiết kế đề xuất được nêu ở trên. [Nguồn5], a core Python developer: “As 3.4beta1 happens tonight, this isn’t going to make 3.4 so i’m bumping this to 3.5. I really like the proposed design outlined above.” [source5]
  • Guido Van Rossum về khả năng thêm scandir vào Python 3.5 (vì đã quá muộn cho 3,4): Tàu cũng đã đi thuyền để thêm scandir () (có hệ điều hành hay pathlib). Bằng mọi cách, hãy thử nghiệm và chuẩn bị sẵn sàng để xem xét cho 3,5, nhưng tôi không muốn thêm nó vào 3,4. [Nguồn6] on the possibility of adding scandir to Python 3.5 (as it was too late for 3.4): “The ship has likewise sailed for adding scandir() (whether to os or pathlib). By all means experiment and get it ready for consideration for 3.5, but I don’t want to add it to 3.4.” [source6]

Hỗ trợ cho bản thân PEP này (hỗ trợ meta?) Đã được Nick Coghlan đưa ra trên Python-dev: Một PEP xem xét tất cả điều này cho 3.5 và đề xuất một API OS.Scandir cụ thể sẽ là một điều tốt. [Nguồn7]

Sử dụng trong tự nhiên

Cho đến nay, việc triển khai

def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total
3 chắc chắn rất hữu ích, nhưng đã được đánh dấu rõ ràng là Beta Beta, vì vậy, nó không chắc chắn việc sử dụng nó có bao nhiêu trong tự nhiên. Ben Hoyt đã có một số báo cáo từ những người sử dụng nó. Ví dụ:

  • Chris F: Tôi đang xử lý một số thư mục khá lớn và một nửa mong muốn phải sửa đổi getdents. Vì vậy, cảm ơn vì đã tiết kiệm cho tôi những nỗ lực. [qua email cá nhân]
  • BSCHOLLNICK: Tôi muốn cho bạn biết về điều này, vì tôi đang sử dụng Scandir làm khối xây dựng cho mã này. Ở đây, một ví dụ điển hình về việc Scandir thực hiện cải thiện hiệu suất triệt để so với Os.ListDir. [Nguồn8]
  • Avram L: Tôi đã thử nghiệm scandir của chúng tôi cho một dự án mà tôi đang làm việc. Có vẻ khá vững chắc, vì vậy điều đầu tiên, chỉ muốn nói công việc tốt đẹp! [qua email cá nhân]
  • Matt Z: Tôi đã sử dụng scandir để đổ nội dung của một mạng lưới trong vòng dưới 15 giây. 13 Dirs gốc, 60.000 tệp trong cấu trúc. Điều này sẽ thay thế một số mã VBA cũ được nhúng trong một bảng tính mất 15-20 phút để làm điều tương tự chính xác. [qua email cá nhân]

Những người khác đã yêu cầu một gói PYPI cho nó, đã được tạo ra. Xem gói PYPI.

Các số liệu thống kê của GitHub có nghĩa là quá nhiều, nhưng Scandir có một số người theo dõi, vấn đề, dĩa, v.v ... Tại đây, các số liệu thống kê kể từ ngày 7 tháng 7 năm 2014:

  • Người theo dõi: 17
  • Sao: 57
  • Phân: 20
  • Vấn đề: 4 mở, 26 đóng

Ngoài ra, vì PEP này sẽ tăng tốc độ os.walk() đáng kể, có hàng ngàn nhà phát triển và kịch bản, và rất nhiều mã sản xuất, sẽ được hưởng lợi từ nó. Ví dụ, trên GitHub, có gần như nhiều cách sử dụng của

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
18 (194.000) như có
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
19 (230.000).

Từ chối ý tưởng

Đặt tên

Ứng cử viên thực sự duy nhất khác cho chức năng này Tên tên là

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
20. Tuy nhiên, các chức năng
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
21 trong Python (chủ yếu được tìm thấy trong Python 2) có xu hướng tương đương iterator đơn giản của các đối tác không phải điều khiển của chúng. Ví dụ,
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
22 chỉ là phiên bản ererator của
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
23, nhưng các đối tượng được trả về là giống hệt nhau. Tuy nhiên, trong trường hợp ____ 19 19, các giá trị trả về là các đối tượng khá khác nhau (đối tượng ____28 so với chuỗi tên tệp), vì vậy điều này có thể được phản ánh bởi sự khác biệt về tên - do đó
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
9.

Xem một số cuộc thảo luận có liên quan về Python-dev.

người hỗ trợ ký đại diện

________ 12/________ 13 Trên Windows Hỗ trợ vượt qua một loài ký tự đại diện như

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
29, vì vậy, những người đầu tiên (bao gồm cả tác giả PEP này) cảm thấy sẽ là một ý tưởng tốt để đưa một đối số từ khóa
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
30 cho chức năng
def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total
3 để người dùng có thể chuyển điều này.

Tuy nhiên, theo suy nghĩ và thảo luận thêm, người ta đã quyết định rằng đây sẽ là ý tưởng tồi, trừ khi nó có thể được thực hiện đa nền tảng (một đối số từ khóa

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
32 hoặc tương tự). Điều này có vẻ đủ dễ dàng lúc đầu-chỉ cần sử dụng hỗ trợ đại diện OS trên Windows và một cái gì đó như
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
33 hoặc
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
34 sau đó trên các hệ thống dựa trên POSIX.

Thật không may, các quy tắc phù hợp với Wildcard Windows chính xác không thực sự được Microsoft ghi lại ở bất cứ đâu và chúng khá kỳ quặc (xem bài đăng trên blog này), có nghĩa là nó rất có vấn đề khi mô phỏng bằng cách sử dụng

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
33 hoặc regexes.

Vì vậy, sự đồng thuận là hỗ trợ Wildcard của Windows là một ý tưởng tồi. Có thể thêm vào một ngày sau đó nếu có một cách đa nền tảng để đạt được nó, nhưng không phải cho phiên bản ban đầu.

Đọc thêm về chủ đề Python-Ideas tháng 11 năm 2012 này và chủ đề Python-Dev tháng 6 năm 2014 này trên PEP 471.

Có nhiều cuộc tranh luận về Python-Dev (xem tin nhắn trong chuỗi này) về việc liệu các phương thức

def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total
8 có nên tuân theo các liên kết tượng trưng hay không (khi các phương thức
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
13 không có tham số
it = os.scandir(path)
while True:
    try:
        entry = next(it)
    except OSError as error:
        handle_error(path, error)
    except StopIteration:
        break
8).

Ban đầu họ đã không (xem các phiên bản trước của mô-đun PEP và Scandir.py này), nhưng Victor Stinner đã đưa ra một trường hợp khá hấp dẫn trên Python-dev rằng theo các liên kết symlink theo mặc định là một ý tưởng tốt hơn, bởi vì:

  • Các liên kết sau thường là những gì bạn muốn (trong 92% trường hợp trong thư viện tiêu chuẩn, các chức năng sử dụng os.listdir()os.stat()4 làm theo Symlinks)
  • Đó là tiền lệ được thiết lập bởi các chức năng tương tự os.stat()4 và
    it = os.scandir(path)
    while True:
        try:
            entry = next(it)
        except OSError as error:
            handle_error(path, error)
        except StopIteration:
            break
    
    6, vì vậy để làm khác sẽ gây nhầm lẫn
  • Với cách tiếp cận không liên kết, nếu bạn muốn theo các liên kết, bạn phải nói điều gì đó như
    def subdirs(path):
        """Yield directory names not starting with '.' under given path."""
        for entry in os.scandir(path):
            if not entry.name.startswith('.') and entry.is_dir():
                yield entry.name
    
    43, đó là vụng về vụng về

Như một trường hợp cụ thể cho thấy phiên bản không liên kết có liên kết có lỗi, tác giả PEP này đã có lỗi do việc kiểm tra chính xác này sai trong việc triển khai

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
44 ban đầu của anh ấy trong scandir.py (xem vấn đề #4 tại đây).

Cuối cùng, không có sự thỏa thuận nào rằng các phương pháp nên tuân theo các liên kết của Symlink, nhưng có sự đồng thuận cơ bản giữa những người tham gia có liên quan nhiều nhất và tác giả PEP này tin rằng trường hợp trên đủ mạnh để đảm bảo theo các liên kết symlink theo mặc định.

Ngoài ra, nó rất đơn giản để gọi các phương thức có liên quan với

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
45 nếu hành vi khác là mong muốn.

Thuộc tính direntry là thuộc tính

Trong một số cách, nó sẽ đẹp hơn cho

def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total
8
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
13 và
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
0 để trở thành thuộc tính thay vì các phương thức, để chỉ ra rằng chúng rất rẻ hoặc miễn phí. Tuy nhiên, đây không phải là trường hợp, vì
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
0 sẽ yêu cầu gọi hệ điều hành trên các hệ thống dựa trên POSIX nhưng không phải trên Windows. Ngay cả os.walk()5 và bạn bè cũng có thể thực hiện cuộc gọi HĐH trên các hệ thống dựa trên POSIX nếu giá trị
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
51 là
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
07 (trên một số hệ thống tệp nhất định).

Ngoài ra, mọi người sẽ mong đợi quyền truy cập thuộc tính

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
53 chỉ tăng
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
54, chứ không phải os.walk()1 trong trường hợp nó thực hiện một cuộc gọi hệ thống theo bìa. Mã gọi sẽ phải có ____ 156/________ 157 xung quanh những gì trông giống như một quyền truy cập thuộc tính đơn giản, và do đó, nó tốt hơn nhiều để tạo ra các phương thức của chúng.

Xem chủ đề Python-dev tháng 5 năm 2013 này, nơi tác giả PEP này đưa ra trường hợp này và có thỏa thuận từ một nhà phát triển cốt lõi.

Các trường Direntry là các đối tượng chỉ thuộc tính thuộc tính tĩnh

Trong thông điệp Python-Dev tháng 7 năm 2014 này, Paul Moore đã đề xuất một giải pháp là một trình bao bọc mỏng của người Viking, trong đó đối tượng

def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total
8 chỉ có các thuộc tính tĩnh:
def get_tree_size(path):
    """Return total size of files in path and subdirs. If
    is_dir() or stat() fails, print an error message to stderr
    and assume zero size (for example, file has been deleted).
    """
    total = 0
    for entry in os.scandir(path):
        try:
            is_dir = entry.is_dir(follow_symlinks=False)
        except OSError as error:
            print('Error calling is_dir():', error, file=sys.stderr)
            continue
        if is_dir:
            total += get_tree_size(entry.path)
        else:
            try:
                total += entry.stat(follow_symlinks=False).st_size
            except OSError as error:
                print('Error calling stat():', error, file=sys.stderr)
    return total
7,
def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total
6 và os.listdir()0, với các thuộc tính
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
62 chỉ có trên Windows . Ý tưởng là sử dụng chức năng cấp thấp hơn, đơn giản hơn như một khối xây dựng cho các chức năng cấp cao hơn.

Lúc đầu, có thỏa thuận chung đơn giản hóa theo cách này là một điều tốt. Tuy nhiên, có hai vấn đề với phương pháp này. Đầu tiên, giả định là

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
63 và các thuộc tính tương tự luôn có mặt trên POSIX, đó là trường hợp (nếu
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
05 không có mặt hoặc là
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
07). Thứ hai, nó có một API khó sử dụng hơn nhiều trong thực tế, vì ngay cả các thuộc tính
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
63 cũng không có mặt trên POSIX, và sẽ cần phải được kiểm tra với
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
67 và sau đó os.stat() gọi nếu chúng có mặt.

Xem phản hồi Python-Dev tháng 7 năm 2014 này từ tác giả PEP này chi tiết tại sao tùy chọn này là một giải pháp không lý tưởng và câu trả lời tiếp theo từ thỏa thuận lồng tiếng cho Paul Moore.

Các trường Direntry đang tĩnh với tùy chọn đảm bảo_lstat

Một lựa chọn có vẻ đơn giản và hấp dẫn khác đã được Nick Coghlan đề xuất trong thông điệp Python-Dev tháng 6 năm 2014 này: Tạo các thuộc tính

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
10 và
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
70 và điền vào thời gian lặp
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
70, nhưng chỉ khi đối số mới
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
72 được quy định trong cuộc gọi
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
9.

Điều này có lợi thế so với những điều trên là bạn có thể dễ dàng nhận được kết quả STAT từ

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
9 nếu bạn cần. Tuy nhiên, nó có nhược điểm nghiêm trọng là xử lý lỗi hạt mịn là lộn xộn, bởi vì ____10 sẽ được gọi (và do đó có khả năng tăng os.walk()1) trong quá trình lặp, dẫn đến một vòng lặp khá xấu xí, được làm bằng tay:

it = os.scandir(path)
while True:
    try:
        entry = next(it)
    except OSError as error:
        handle_error(path, error)
    except StopIteration:
        break

Hoặc điều đó có nghĩa là

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
9 sẽ phải chấp nhận đối số
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
78 - một hàm để gọi khi xảy ra lỗi
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
0 trong quá trình lặp. Điều này dường như đối với tác giả PEP, không trực tiếp cũng như Pythonic như ________ 156/________ 157 xung quanh một cuộc gọi os.walk()2.

Một nhược điểm khác là os.scandir() được viết để làm cho mã nhanh hơn. Luôn gọi os.scandir()9 trên POSIX sẽ không mang lại bất kỳ tốc độ tăng tốc. Trong hầu hết các trường hợp, bạn không cần đối tượng

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
5 đầy đủ - các phương thức
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
13 là đủ và thông tin này đã được biết đến.

Xem Ben Hoyt sườn tháng 7 năm 2014 Trả lời cuộc thảo luận tóm tắt điều này và chi tiết lý do tại sao ông nghĩ rằng đề xuất PEP 471 ban đầu là một trong những điều đúng đắn.

Trả về các giá trị là (tên, stat_result) hai bộ phận

Ban đầu, tác giả PEP này đã đề xuất khái niệm này như một hàm gọi là

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
87 mang lại hai bộ đôi (tên, stat_result). Điều này có lợi thế là không có loại mới được giới thiệu. Tuy nhiên,
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
5 chỉ được lấp đầy một phần trên các hệ thống dựa trên POSIX (hầu hết các trường được đặt thành
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
89 và các quirks khác), vì vậy chúng không thực sự là đối tượng
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
5, và điều này sẽ phải được ghi lại kỹ lưỡng khác với os.stat().

Ngoài ra, Python có hỗ trợ tốt cho các đối tượng thích hợp với các thuộc tính và phương thức, tạo ra một API đơn giản và đơn giản hơn hai bộ phận. Nó cũng làm cho các đối tượng

def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total
8 có thể mở rộng hơn và chứng minh trong tương lai khi các hệ điều hành thêm chức năng và chúng tôi muốn đưa vào điều này vào
def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total
8.

Xem thêm một số cuộc thảo luận trước đây:

  • Tháng 5 năm 2013 Python-dev Chủ đề nơi Nick Coghlan đưa ra trường hợp ban đầu cho một đối tượng kiểu ____ 28.
  • Tháng 6 năm 2014 Python-dev Chủ đề nơi Nick Coghlan đưa ra (một trường hợp khác) tốt chống lại cách tiếp cận hai tuple.

Trả về các giá trị bị quá tải các đối tượng Stat_Result

Một cách khác được thảo luận là làm cho các giá trị trả về được quá tải các đối tượng

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
5 với các thuộc tính
def get_tree_size(path):
    """Return total size of files in path and subdirs. If
    is_dir() or stat() fails, print an error message to stderr
    and assume zero size (for example, file has been deleted).
    """
    total = 0
    for entry in os.scandir(path):
        try:
            is_dir = entry.is_dir(follow_symlinks=False)
        except OSError as error:
            print('Error calling is_dir():', error, file=sys.stderr)
            continue
        if is_dir:
            total += get_tree_size(entry.path)
        else:
            try:
                total += entry.stat(follow_symlinks=False).st_size
            except OSError as error:
                print('Error calling stat():', error, file=sys.stderr)
    return total
7 và
def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total
6. Tuy nhiên, ngoài việc này là một loại quá tải kỳ lạ (và căng thẳng!)

Trả về các giá trị là các đối tượng pathlib.path

Với mô -đun thư viện tiêu chuẩn mới của Antoine Pitrou, os.walk()3, lúc đầu có vẻ như là một ý tưởng tuyệt vời cho

def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
9 để trả về các trường hợp os.listdir()5. Tuy nhiên, các chức năng ____ 95
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
13 và
def subdirs(path):
    """Yield directory names not starting with '.' under given path."""
    for entry in os.scandir(path):
        if not entry.name.startswith('.') and entry.is_dir():
            yield entry.name
0 không được lưu trữ rõ ràng, trong khi
def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total
3 phải lưu trữ chúng theo thiết kế, bởi vì nó (thường) trả về các giá trị từ cuộc gọi hệ thống lặp thư mục ban đầu.

Và nếu các trường hợp ____995 được trả về bởi các giá trị thống kê được lưu trong bộ nhớ cache, nhưng các đối tượng os.listdir()5 thông thường rõ ràng don don, điều đó sẽ nhiều hơn một chút khó hiểu.

Guido Van Rossum đã từ chối rõ ràng os.listdir()5 Bộ nhớ đệm trong bối cảnh scandir ở đây, làm cho os.listdir()5 trở thành một lựa chọn tồi cho các giá trị trả lại scandir.

Có thể cải thiện

Có nhiều cải tiến có thể mà người ta có thể thực hiện để Scandir, nhưng đây là một danh sách ngắn của một số tác giả PEP này có trong tâm trí:

  • Scandir có khả năng có thể được tăng tốc thêm bằng cách gọi
    def subdirs(path):
        """Yield directory names not starting with '.' under given path."""
        for entry in os.scandir(path):
            if not entry.name.startswith('.') and entry.is_dir():
                yield entry.name
    
    4 /
    def subdirs(path):
        """Yield directory names not starting with '.' under given path."""
        for entry in os.scandir(path):
            if not entry.name.startswith('.') and entry.is_dir():
                yield entry.name
    
    3 nói 50 lần mỗi khối
    def get_tree_size(path):
        """Return total size of files in given path and subdirs."""
        total = 0
        for entry in os.scandir(path):
            if entry.is_dir(follow_symlinks=False):
                total += get_tree_size(entry.path)
            else:
                total += entry.stat(follow_symlinks=False).st_size
        return total
    
    15 để nó ở trong mô -đun mở rộng C lâu hơn và có thể nhanh hơn một chút. Cách tiếp cận này đã được thử nghiệm, nhưng được đề xuất bởi số 11406 bởi Antoine Pitrou. [Nguồn9]
  • Scandir có thể sử dụng một danh sách miễn phí để tránh chi phí phân bổ bộ nhớ cho mỗi lần lặp - một danh sách ngắn miễn phí 10 hoặc thậm chí 1 có thể giúp đỡ. Được đề xuất bởi Victor Stinner trên một chủ đề Python-Dev vào ngày 27 tháng Sáu.

Thảo luận trước

  • Chủ đề ban đầu tháng 11 năm 2012 Ben Hoyt bắt đầu trên Python-Ideas về việc tăng tốc os.walk()
  • Vấn đề Python 11406, bao gồm đề xuất ban đầu cho chức năng giống như scandir
  • Hơn nữa vào tháng 5 năm 2013, chủ đề Ben Hoyt bắt đầu trên Python-Dev đã tinh chỉnh API
    def subdirs(path):
        """Yield directory names not starting with '.' under given path."""
        for entry in os.scandir(path):
            if not entry.name.startswith('.') and entry.is_dir():
                yield entry.name
    
    9
  • Tháng 11 năm 2013 Chủ đề Ben Hoyt bắt đầu trên Python-Dev để thảo luận về sự tương tác giữa Scandir và mô-đun os.walk()3 mới
  • Tháng 6 năm 2014 Chủ đề Ben Hoyt bắt đầu trên Python-Dev để thảo luận về phiên bản đầu tiên của PEP này, với cuộc thảo luận sâu rộng về API
  • Chủ đề đầu tiên vào tháng 7 năm 2014, Ben Hoyt bắt đầu trên Python-Dev để thảo luận về các bản cập nhật của anh ấy cho PEP 471
  • Chủ đề thứ hai vào tháng 7 năm 2014, Ben Hoyt đã bắt đầu trên Python-Dev để thảo luận về các quyết định còn lại cần thiết để hoàn thiện PEP 471, cụ thể là liệu các phương thức
    def get_tree_size(path):
        """Return total size of files in given path and subdirs."""
        total = 0
        for entry in os.scandir(path):
            if entry.is_dir(follow_symlinks=False):
                total += get_tree_size(entry.path)
            else:
                total += entry.stat(follow_symlinks=False).st_size
        return total
    
    8 có nên tuân theo các liên kết symlink theo mặc định
  • Câu hỏi về StackoverFlow về lý do tại sao os.walk() chậm và con trỏ về cách sửa nó (điều này đã truyền cảm hứng cho tác giả của PEP này từ rất sớm)
  • Betterwalk, tác giả PEP này đã cố gắng trước đây, trên đó mã Scandir dựa trên

Bản quyền

Tài liệu này đã được đặt trong phạm vi công cộng.