Học Python/Chương VI
Xử lí ngọai lệ
[sửa]Giống như nhiều ngôn ngữ lập trình khác , Python có quản lí ngọai lệ qua try ... except blocks . Python dùng try ... except để quản lí exceptions và raise để phát sinh chúng . Ngọai lệ thì ở mọi nơi trong Python . Hầu như môi module trong thư viện chuẩn python dùng chúng , và Python sẽ đưa chúng vào trong nhiều tình huống khác nhau . Bạn đã xem chúng lập đi lập lại trong quyển sách này rồi
- Truy cập một từ điển với khóa không tồn tại sẽ là " KeyError exception " .
- Tìm tên danh sách cho một giá trị không tồn tại sẽ là " ValueError exception ".
- Gọi một phương thức không tồn tại sẽ là " AttributeError exception ".
- Tham chiếu một biến không tồn tại sẽ là một " NameError exception ".
- Trộn datatypes bị ép buộc sẽ là một " TypeError exception ".
Ví dụ : Mở một file không tồ tại
>>> fsock = open("/notthere", "r") Traceback (innermost last): File "<interactive input>", line 1, in ? IOError: [Errno 2] No such file or directory: '/notthere' >>> try: ... fsock = open("/notthere") ... except IOError: ... print "The file does not exist, exiting gracefully" ... print "This line will always print"
- Dùng built-in mở hàm , bạn có thể mở một file để đọc . Nhưng file không tồn tại , vì vậy điều này đưa IOError exception . Kể từ khi bạn không cung cấp bất cứ kiểm tra dứt khóat nào , cho một ngọai lệ IOError , python chỉ in vài thông tin debugging ra , về điều gì đã xảy ra và sau đó thóat.
- Bạn đang cố gắng mở cùng file không tồn tại , nhưng lúc này bạn đang làm điều đó trong một try ... except block .
- Khi phương thức mở ngọai lệ IOError , you're ready làm điều đó . Ngọai lệ IOError : dòng bắt ngọai lệ và thi hành đọan code của chính bạn , trong trường hợp này chỉ in nhiều hơn một thông báo lỗi .
- Một ngọai lệ được nắm , xứ lí tiếp tục bình thường trên dòng sau khi try ... except block . Chú ý rằng dòng này sẽ luôn luôn in , mặc dù không một ngọai lệ nào xảy ra . Nếu bạn thật sự đã có gọi một file có trong thư mục của bạn , gọi để mở bình thường đã thành công , nguyên nhân ngọai lệ sẽ bỏ qua, và dòng này sẽ vẫn còn được thi hành .
Dùng ngoại lệ cho các mục đích khác
[sửa]Có nhiều cách khác dùng cho ngọai lệ bên cạnh quản lí điều kiện lổi thật sự . Thông thường dùng hàm thư viện python chuẩn là cố gắng để import một module , và sau đó kiểm tra mặc dù nó đã làm việc . Import một module không tồn tại , sẽ đưa một ngọai lệ ImportError . Bạn có thể dùng điều này để định nghĩa nhiều cấp hàm căn bản trên những module thì sẵn sàng để chạy , hoặc để hổ trợ nhiều platforms ( Nơi mà sự đọan code về platform−specific thì được chia thành những module khác nhau ).
Bạn có thể định nghĩa ngọai lệ của chính bạn bởi tạo một lớp mà kế thừa từ lớp ngọai lệ built−in ,và sau đó đưa ngọai lệ của bạn với raise command .
Ví dụ : Hàm hổ trợ hệ thống nền
# Bind the name getpass to the appropriate function try: import termios, TERMIOS except ImportError: try: import msvcrt except ImportError: try: from EasyDialogs import AskPassword except ImportError: getpass = default_getpass else: getpass = AskPassword else: getpass = win_getpass else: getpass = unix_getpass
- termios là một module UNIX−specific cung cấp điều khiển múc thấp tên nhập đầu cuối . Nếu module này thì không sẵn sàng (Bởi vì nó thì không trên hệ thống của bạn , hay hệ thống không hổ trợ ), import thất bại và python đưa một ImportError , và bạn sẽ bắt .
- OK, Bạn đã không có termios, vì vậy chúng ta thử msvcrt,là một module Windows−specific mà cung cấp một API với nhiều hàm hửu ít trong Microsot Visual C++ . Nếu import này thất bại , Python sẽ đửa một ImportError mà bạn có thể bắt .
- Nếu điều đầu tiên vầ thứ hai không làm việc , bạn thử import một hàm từ EasyDialogs là một module Mac OS−specific cung cấp các hàm pop up dialog boxes của nhiều lọai . Một lần nửaa , nếu import này thất bại Python sẽ đưa một ImportError , mà bạn có thể bắt .
- Không một module platform−specific thì sẳn sàng (thì khả thi , kể từ khi Python import nhiều platforms khác nhau ), vì vậy bạn cần để trở lại trên một password mặc định hàm input ( được định nghĩa ).
- A try...except block có thể có một mệnh đệ else , giống như phát biểu if . Nếu không ngoại lệ được đưa xuốt trong try block , mệnh đề else thì thi hành sau đấy . Trong trường hợp này , điều đó có nghĩa là EasyDialogs import AskPassword , vì vậy bạn sẽ trói getpass để hàm AskPassword. Mỗi một try ... except blocks khác tương tự mệnh để else .
Làm việc với đối tượng file
[sửa]Python có một hàm built-in , open , cho mở file trên ổ cứng. open returns một đối tượng file , có phương thức và thuộc tính cho việc lấy thông tin về thao tác mở file .
Ví dụ : Mở một file
>>> f = open("/music/_singles/kairo.mp3", "rb") >>> f <open file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988> >>> f.mode 'rb' >>> f.name '/music/_singles/kairo.mp3'
- Phương thức mở có thể lấy ba tham số : tên file , mode , và một tham số đệm . Duy nhất tham số đầu tiên , tên file được yêu cầu ; tham số thứ hai được chọn . Nếu không đặc tả , file được mở cho việc đọc trong text mode . Đây là bạn đang mơi file cho đọc trong binary mode .(in open.__doc__ hiển thị một giải thích về tất cả modes khả khi )
- Hàm mở trả về một đối tượng ( ngay bây giờ ,điều này sẽ không ngạc nhiêun với bạn ). Một đối tượng file có vài thuộc tính hữu dụng .
- Thuộc tính mode của một đối tượng file bảo bạn trong mode mà file đang được mở .
- Thuộc tính tên của đối tượng file bảo bạn tên đối tượn file đang được mở .
Đọc file
[sửa]Sau khi bạn mở một file , điều đâu tien bạn sẽ muốn làm là đọc từ nó .
Ví dụ : Đọc file
>>> f <open file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988> >>> f.tell() 0 >>> f.seek(−128, 2) >>> f.tell() 7542909 >>> tagData = f.read(128) >>> tagData 'TAGKAIRO****THE BEST GOA ***DJ MARY−JANE*** Rave Mix 2000http://mp3.com/DJMARYJANE \037' >>> f.tell() 7543037
- Một đối tượng file duy trì trang thái về file nó đang được mở . Bảo phương thức của một đối tượng file về vị trí hiện tại trong file . Kể từ khi bạn không có làm bất cứ điều gì với file này , vị trí hiện tại trong file là 0 , là bắt đầu của một file .
- Phương thức seek của một đối tượng file di chuyển tới vị trí khác trong mở file . Tham số thứ hai đặc tả :
- 0 nghĩa là di chuyển tới một vị trí tương đối.
- 1 nghĩa là di chuyển tới vi trí liên quan.
- 2 nghĩa là di chuyển đến vị trí liên quan , cuối cùng của một file .
- The tell method confirms that the current file position has moved.
- Phương thức read đọc một số đặc tả số byte từ mở file và trả về một chuỗi với dử liệu được đọc .
Tham số chọn , đặc tả số lớn nhất của bytes để đọc . Nếu không tham số được đặc tả ,read sẽ đọc đến tân khi cuối của file . ( Bạn chỉ đơn giản nói đọc ở đây , từ lúc đó bạn biết chính xác bạn đang ở đây trong file ) . Dử liệu đọc được chỉ định tới biến tagData , và vị trí hiện hành được cập nhật căn bản trên nhiều byte được đọc .
- Phương thức tell , xác nhận rằng vị trí hiện hành đã được di chuyển . Nếu bạn là một phép tóan , bạn sẽ thấy rằng sau khi đọc 128 bytes , vi trí đã tăng lên 128 .
Đóng tập tin
[sửa]Mở files lãng phí tài nguyên , và phụ thuôc và file mode , chương trình khác đã không thể truy cậy chúng . Điều này quan trọng để đóng file sớm khi bạn hòan thành với chúng .
Ví dụ : Closing a File
>>> f <open file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988> >>> f.closed False >>> f.close() >>> f <closed file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988> >>> f.closed True >>> f.seek(0) Traceback (innermost last): File "<interactive input>", line 1, in ? ValueError: I/O operation on closed file >>> f.tell() Traceback (innermost last): File "<interactive input>", line 1, in ? ValueError: I/O operation on closed file >>> f.read() Traceback (innermost last): File "<interactive input>", line 1, in ? ValueError: I/O operation on closed file >>> f.close()
- Thuộc tính closed của một đối tượng file cho biết trong bất cứ trường hợp đối tượng có một file mở hay không . Trong trường hợp này , file là vẫn còn mở ( closed là False ).
- Để đóng một file , gọi phương thức đóng của một đối tượng . Điều này tự do khóa mà bạn đang giử trên file .
- Thuộc tính closed xác nhận rằng file được đóng .
Ví dụ : Đối tượng MP3FileInfo
try: fsock = open(filename, "rb", 0) try: fsock.seek(−128, 2) tagdata = fsock.read(128) finally: fsock.close() . . .
except IOError: pass
- Bởi vì mở và đọc và một file là mạo hiểm và có thể đưa ngọai lệ, tất cả code này thì bao phủ trong một tre...except block .
- Hàm mở đưa một IOError ( có lẽ file không tồn tại ) .
- Phương thức seek có thể đưa một IOError ( có lẽ file thì nhỏ hơn 128 bytes ) .
- Phương thức read có thể đưa một IOError ( có lẽ disk có một bad sector , hay nó thì trên mạng ,và mạng tắt ).
- Điều này thì mới : a try...finally block. Một lần file được mở thành công bởi hàm mở , bạn muốn làm một tuyệt đối dể chắc rằng bạn đóng nó , ngay cả nếu một ngoại lệ bởi phương thức seek hay read .
Đó là tại sao try ... finally block là cho : code trong block finally se luôn luôn được thực thi , ngay cả nếu vài thứ trong truy nổi lên một ngọai lệ .
Ghi file
[sửa]Trong khi bạn mong muốn , bạn có thể cũng viết file trong nhiều các giống nhau mà bạn đọc từ chúng . Có 2 cách cơ bản .
- Mode "Append" sẽ thêm dử liệu vào cuối của file .
- Mode "write" sẽ ghi đè lên file .
Cả hai mode sẽ tạo file một cách tự động , nếu nó không thật sừ tồn tại . Chỉ open nó vàbắt đầu viết
Ví dụ : Ghi file
>>> logfile = open('test.log', 'w') >>> logfile.write('test succeeded') >>> logfile.close() >>> print file('test.log').read() test succeeded >>> logfile = open('test.log', 'a') >>> logfile.write('line 2') >>> logfile.close() >>> print file('test.log').read() test succeededline 2
- Bạn bắt đầu liều lĩnh tạo file mới test.log hay viết đè lên file tồn tại , và mở file để viết ( tham số thứ hai "w" nghĩa là mở file để viết ) . Tôi hy vọng bạn đã không chăm sóc về nội dung trước của file , bởi vì nó sẽ được làm ngay bây giờ .
- Bạn có thể thêm dữ liệu tới file được tạo mới với phương thức write , đối tượng file được trả về bởi open .
lọc với vòng lặp for
[sửa]Giống như hầu hết ngôn ngữ khác , Python có vòng lặp . Lí do duy nhất bạn không thấy chúng đến tận bây giờ là python thì tốt nhiều thứ khác , bạn không cần chúng thường hơn .
Phần đông ngôn ngữ khác không có sức mạnh trong danh sách datatype giống python, vì vậy kết thúc làmg nhiều việc , đặc tả start , end và step để định nghĩa một phạm vi số nguyên hay kí tự hay thực thể làm đi làm lại . Nhưng trong bython , một vòng lặp for đơn giản lập đi lập lại qua một danh sách.
Ví dụ : giới thiệu vòng lặp for
>>> li = ['a', 'b', 'e'] >>> for s in li: ... print s a b e >>> print "\n".join(li) a b e
- Cú pháp cho vòng lặp for thì tương tự bao gôm danh sách . li là một danh sách , và s sẽ lấy giá trị của mỗi phần tử trong sự trả về , bắt đầu từ phần tử đầu tiên .
- Giống một phát biểu if hay bất kì block thụt vào khác , một vòng lặp có thể có bất cứ số của dòng code trong nó .
- Điều này là nguyên nhân bạn không thấy trong lặp , bạn không cần nó .
Ví dụ : bộ đếm đơn giản
>>> for i in range(5): ... print i 0 1 2 3 4 >>> li = ['a', 'b', 'c', 'd', 'e'] >>> for i in range(len(li)): ... print li[i] a b c d e
- Sự quy cho giá trị liên tiếp nhau�, phạm vi kết quả một danh sách của số nguyên , cái mà bạn lặp thông qua .
- Đừng bao giờ làm điều này . Đây là Visual Basic−style nghĩ.
Ví dụ : lọc thông qua từ điển
>>> import os >>> for k, v in os.environ.items(): ... print "%s=%s" % (k, v) USERPROFILE=C:\Documents and Settings\mpilgrim OS=Windows_NT COMPUTERNAME=MPILGRIM USERNAME=mpilgrim
[...snip...] >>> print "\n".join(["%s=%s" % (k, v) ... for k, v in os.environ.items()]) USERPROFILE=C:\Documents and Settings\mpilgrim OS=Windows_NT COMPUTERNAME=MPILGRIM USERNAME=mpilgrim
- os.environ là một từ điển của biến môi trường được định nghĩa trên hệ thống của bạn . Trong cửa sổ windows , có người dùng của bạn và biến hệ thống được truy cập từ MS-DOS . Trong UNIX , chúng là biến mở rộng trong shell's startup scripts . Trong Mac OS , không có khái niệm biến môi trường , vì vậy thự viện này rổng .
- os.environ.items() trả về một danh sách của tuples : [(key1, value1), (key2, value2), ...]. Vòng lặp cho sự lặp đi lặp lại thông qua danh sách này . Vòng tròn đâu tiên, nó quy cho key 1 tới k và giá trị value1 tới v, vì vậy k = USERPROFILE và v = C:\Documents and Settings\mpilgrim. Trong vòng tròn thứ hai , k lấy khóa thứ hai , OS , và v lấy giá trị tương ướng , Window_NT .
- Với nhiều biến quy cho và danh sách bao gồm , bạn có thể thay thế tòan thể cho vòng lặp với phát biểu đơn .
Ví dụ : vòng lặp trong MP3FileInfo
tagDataMap = {"title" : ( 3, 33, stripnulls), "artist" : ( 33, 63, stripnulls), "album" : ( 63, 93, stripnulls), "year" : ( 93, 97, stripnulls), "comment" : ( 97, 126, stripnulls), "genre" : (127, 128, ord)} . . . if tagdata[:3] == "TAG": for tag, (start, end, parseFunc) in self.tagDataMap.items(): self[tag] = parseFunc(tagdata[start:end])
- tagDataMap là một thuộc tính lớp mà định nghĩa tag bạn đang tìm kiếm cho một MP3 File . Tags được lưu trử trong fixed−length fields. Một khi bạn dọc 128 bytes cuối của file bytes thứ 3 tới 32 luôn luôn là tựa , 33 tới 62 luôn là tên của tác giả , 63 tới 92 là tên album , và vị vậy mức độ . chú ý rằng tagDataMap là một từ điển của tuples, và mỗi một tuple chứa hai số nguyên và một tham chiếu .
- Điều này trông phức tạp , nhưng nó thì không . Cấu trúc của biến for ánh xạ cấu trúc của phần tử danh sách trả về item. Nhớ rằng items trả về một danh sách của tuples của form ( key , value ). Phần tử đầu tiên của danh sách là ("title", (3, 33, <function stripnulls>)) , vì vậy vòng chạy đầu tiên , tag lấy "title" , start lấy 3 , end gets 33 , và parseFunc lấy hàm .
Sử dụng sys.modules
[sửa]Modules giống mọi thứ khác trong Python , là đối tượng . Mội khi import , bạn có thể luôn lấy một tham chiếu tới từ điển địa phương sys.modules.
Ví dụ : Giới thiệu sys.modules
>>> import sys >>> print '\n'.join(sys.modules.keys()) win32api os.path os exceptions __main__ ntpath nt sys __builtin__ site signal UserDict stat
- Module sys chứa thông tin cấp hệ thống , như là phiên bản python mà bạn đang dùng . chạy ( sys.version hay sys.version_info )và lựa chọn system-level như là cho phép đệ quy sâu tối đa
( sys.getrecursionlimit() và sys.setrecursionlimit()).
- sys.modules là một từ điển chứa tất cả modules mà có import từ khi Python đã bắt đầu . Khóa là tên của module , giá trị là đối tượng module . Chú ý rằng cái này nhiều hơn những module bạn đã import .
Python đặt trước vài modules khi bắt đầu , và nếu bạn đang dùng Python IDE , sys.modules chứa tất cả modules imported bởi tất cả chương trình bạn chạy trong IDE .
Ví dụ : Dùng sys.modules
>>> import fileinfo >>> print '\n'.join(sys.modules.keys()) win32api os.path os fileinfo exceptions __main__ ntpath nt sys __builtin__ site signal UserDict stat >>> fileinfo <module 'fileinfo' from 'fileinfo.pyc'> >>> sys.modules["fileinfo"] <module 'fileinfo' from 'fileinfo.pyc'>
- Trong khi modules mới được import , chúng được thêm vào sys.modules. Python đã nạp và giấu module trong sys.modules. vì vậy import lần hai thì đơn giản tra cứu từ điển .
- Đưa tên ( như là một chuổi ) của bất kì module import trước đây , Bạn có thể lấy một tham chiếu tới module của nó thông qua từ điển sys.modules
Ví dụ : Thuộc tính lớp __module__
>>> from fileinfo import MP3FileInfo >>> MP3FileInfo.__module__ 'fileinfo' >>> sys.modules[MP3FileInfo.__module__] <module 'fileinfo' from 'fileinfo.pyc'>
- Mỗi một lớp Python có một lớp thuộc tính built-in __module__ .
- So sánh điều này với thư viện sys.modules , bạn lấy được một tham chiếu tới module , cái mà trong lớp được định nghĩa .
Ví dụ : sys.modules trong fileinfo.py
def getFileInfoClass(filename, module=sys.modules[FileInfo.__module__]): "get file info class from filename extension" subclass = "%sFileInfo" % os.path.splitext(filename)[1].upper()[1:] return hasattr(module, subclass) and getattr(module, subclass) or FileInfo
- Đây là một hàm với 2 tham số . tên file được đòi hỏi , nhưng module là lựa chọn mặc định tới module mà chứa lớp FileInfo .Điều này không hiểu quả , bởi vì bạn có thể mong muốn Python ước lượng biểu thức sys.modules mổi lần hàm được gọi . Thực tế , Python ước lượng giá trị mặc định một lần duy nhất . Lần đầu tiên module được import . Bạn không bao giờ gọi hàm này với một tham số là module ,vì vậy module phục vụ như là một function-level constant .
- Bạn đã biết về getattr , lấy một tham chiếu tới một đối tượng bởi tên . hasattr là một hàm bổ sung để kiểm tra một đối tượng không đúng có thuộc tính đặc biệt . Trong trường hợp này , mặc dù một module có một lớp riêng biệt ( mặc dù nó làm việc cho bất cứ đối tượng hay bất kì thuộc tính )
Làm việc với mục lục
[sửa]module os.path có vài hàm serveral trong thao tác file và thư mục . Ở đây , chúng ta đang tìm kiếm tại pathnames và liệt kê nội dung của thư mục
Ví dụ : Xây dụng tên đường dẫn
>>> import os >>> os.path.join("c:\\music\\ap\\", "mahadeva.mp3") 'c:\\music\\ap\\mahadeva.mp3' >>> os.path.join("c:\\music\\ap", "mahadeva.mp3") 'c:\\music\\ap\\mahadeva.mp3' >>> os.path.expanduser("~") 'c:\\Documents and Settings\\mpilgrim\\My Documents' >>> os.path.join(os.path.expanduser("~"), "Python") 'c:\\Documents and Settings\\mpilgrim\\My Documents\\Python'
- os.path là một tham chiếu tới một module , phụ thuộc vào platform của bạn .
- Hàm join của cấu trúc os.path một tên đường dẩn bên ngòai của một hay nhiều đường dẩn đặc biệt . Trong trường hợp này , nó đơn giản móc nối chuỗi (Chú ý rằng sự chia tên đường dẩn trên wondows thì khó chịu bởi vì kí tự dấu chéo haracter cần phải được bỏ).
- Trong trường hợp này , nói sẽ thêm dấu chéo đặc biệt tới tên đường dẩn trước khi nối nó vào tên file . Tôi đã vui mừng khi tôi khám phá điều này , từ khi addSlashIfNecessary là một của hàm nhỏ ngu xuẩn tôi luôn luôn cần để viết khi xây hộp công cụ của tôi trong một ngôn ngữ mới
- expanduser sẽ mở rộng tên đường dẩn , sử dụng đê miêu tả , thư mục home hiện hành của user. Điều này làm việc trên bất cứ platform nơi mà người sử dụng có một thư mục home , giống Windows, UNIX, and Mac OS X; nó không có hiệu ứng trên Mac OS.
- Kỷ thuật so sánh này , bạn có thể xây đường dẫn cho từ điển và file trong user's home directory .
Ví dụ : Tách tên đường dẫn
>>> os.path.split("c:\\music\\ap\\mahadeva.mp3") ('c:\\music\\ap', 'mahadeva.mp3') >>> (filepath, filename) = os.path.split("c:\\music\\ap\\mahadeva.mp3") >>> filepath 'c:\\music\\ap' >>> filename 'mahadeva.mp3' >>> (shortname, extension) = os.path.splitext(filename) >>> shortname 'mahadeva' >>> extension '.mp3'
- Hàm split tách một đường dẩn đầy đủ và trả về một tuple chứa đường dẩn và tên file . Nhớ khi tôi nói bạn có thể có dùng nhiều biến assign để trả về giá trị bội số của hàm .
- Bạn quy cho giá trị trả vể của hàm split vào trong một tuple của hai biến . Mỗi một biến truy xuất giá trị của phần tử tương ứng được trả về tuple .
- Biến đầu tiên , file đường dẫn , tiếp nhận giá trị của phần tử đầu tiên của tuple trả về split đường dẩn file .
- Biến thứ hai , tên file , tiếp nhận giá trị của phần tử thứ hai của tuple trả về split tên file .
- os.path cũng chứa một hàm splittext , tách tên file và trả về một tuple chứa tên file và đuôi mở rộng . Bạn dùng cùng kỹ thuật để quy cho mỗi một chúng biến riêng lẽ .
Ví dụ : Liệt kê thư mục
>>> os.listdir("c:\\music\\_singles\\") ['a_time_long_forgotten_con.mp3', 'hellraiser.mp3', 'kairo.mp3', 'long_way_home1.mp3', 'sidewinder.mp3', 'spinning.mp3'] >>> dirname = "c:\\" >>> os.listdir(dirname) ['AUTOEXEC.BAT', 'boot.ini', 'CONFIG.SYS', 'cygwin', 'docbook', 'Documents and Settings', 'Incoming', 'Inetpub', 'IO.SYS', 'MSDOS.SYS', 'Music', 'NTDETECT.COM', 'ntldr', 'pagefile.sys', 'Program Files', 'Python20', 'RECYCLER', 'System Volume Information', 'TEMP', 'WINNT'] >>> [f for f in os.listdir(dirname) ... if os.path.isfile(os.path.join(dirname, f))]
['AUTOEXEC.BAT', 'boot.ini', 'CONFIG.SYS', 'IO.SYS', 'MSDOS.SYS', 'NTDETECT.COM', 'ntldr', 'pagefile.sys'] >>> [f for f in os.listdir(dirname) ... if os.path.isdir(os.path.join(dirname, f))] ['cygwin', 'docbook', 'Documents and Settings', 'Incoming', 'Inetpub', 'Music', 'Program Files', 'Python20', 'RECYCLER', 'System Volume Information', 'TEMP', 'WINNT']
- Hàm listdir lấy một tên đường dẩn và trả về một danh sách của nội dung của thư mục .
- listdir returns both files and folders, with no indication of which is which.
- Bạn có thể dùng danh sách lọc và hàm isfile của module os.path tách riêng file từ thư mục . isfile lấy tên đường dẫn và trả về 1 nếu đường dẩn miêu tả một file , và 0 là ngược lại . Đây là bạn đang dùng os.path.join để đảm bảo một đường dẩn đầy đủ , nhưng isfile củng làm việc với một đường dẩn đặc biệt , liên quan tới thự mục làm việc hiện hành . Bạn có thể dùng os.getcwd() để lấy thư mục làm việc hiện hành .
- os.path also có một hàm isdir , trả về 1 nếu đường dẩn miêu tả một thư mục , và 0 ngược lại . Bạn có thể dùng điều này để lấy danh sách của các thư mục con trong thư mục.
Ví dụ : liệt kê thư mục trong fileinfo.py
def listDirectory(directory, fileExtList): "get list of file info objects for files of particular extensions" fileList = [os.path.normcase(f) for f in os.listdir(directory)] fileList = [os.path.join(directory, f) for f in fileList if os.path.splitext(f)[1] in fileExtList]
- os.listdir(directory) trả về một danh sách của tất cả các files và folder trong thư mục .
- lọc thông qua danh sách với f , bạn dùng os.path.normcase(f) để bình thường tùy theo trường hợp để hệ thống họat động mặc định . normcase là môt hàm hữa dụng mà bù cho trường hợp nhạy cảm tháo tác trên hệ thống nhu8 mahadeva.mp3 and mahadeva.MP3 là ví dụ . Cho ví dụ , trên Windows và Mac OS, normcase sẽ chuyển thực thể tên file thành chữ thường .Trên hệ thông tương thích UNIX , nó sẽ trả về tên file không thay đổi .
- Bộ lọc thông qua danh sách bình thường với f lần nữa , bạn dùng os.path.splitext(f) để tách mỗi tên file thành tên và đuôi mở rộng .
Ví dụ : Liệt kê thư mục với glob
>>> os.listdir("c:\\music\\_singles\\") ['a_time_long_forgotten_con.mp3', 'hellraiser.mp3', 'kairo.mp3', 'long_way_home1.mp3', 'sidewinder.mp3', 'spinning.mp3'] >>> import glob >>> glob.glob('c:\\music\\_singles\\*.mp3') ['c:\\music\\_singles\\a_time_long_forgotten_con.mp3', 'c:\\music\\_singles\\hellraiser.mp3', 'c:\\music\\_singles\\kairo.mp3', 'c:\\music\\_singles\\long_way_home1.mp3', 'c:\\music\\_singles\\sidewinder.mp3', 'c:\\music\\_singles\\spinning.mp3'] >>> glob.glob('c:\\music\\_singles\\s*.mp3') ['c:\\music\\_singles\\sidewinder.mp3', 'c:\\music\\_singles\\spinning.mp3'] >>> glob.glob('c:\\music\\*\\*.mp3')
- Trong khi bạn thấy dể dàng , os.listdir đơn giản lấy một đường dẫn thư mục và liệt kê tất cả file và thư mục .
- glob module, lấy một wildcard và trả về đường dẫn đầy đủ của tất cả files và từ điển ánh xạ tới wildcard . Wildcard là một đường dẩn thư mục "*.mp3" , sẽ ánh xạ tới các file . Chú ý mỗi phần tử trả về danh sách liệt kê rồi ,bao gồm đường dẫn đầy đủ của file . Tất cả files .mp3 . Chú ý rằng mỗi phần tử danh sách trả về , bao gồm tên đường dẫn đầy đủ của file . Nếu bạn muốn tìm tất cả file in thư mục mà bắt đầu với "s' và kết thức với ".mp3" , bạn có thể là điều đó nửa .
Đặt tất cả chúng cùng nhau
[sửa]Ví dụ : listDirectory
def listDirectory(directory, fileExtList): "get list of file info objects for files of particular extensions" fileList = [os.path.normcase(f) for f in os.listdir(directory)] fileList = [os.path.join(directory, f) for f in fileList if os.path.splitext(f)[1] in fileExtList] def getFileInfoClass(filename, module=sys.modules[FileInfo.__module__]): "get file info class from filename extension" subclass = "%sFileInfo" % os.path.splitext(filename)[1].upper()[1:] return hasattr(module, subclass) and getattr(module, subclass) or FileInfo return [getFileInfoClass(f)(f) for f in fileList]
- listDirectory thì thu hút module đối tượng. Nó lấy một thư mục (giống c:\music\_singles\ in my case) và liệt kê file quan tâm (giống ['.mp3']), và nó trả về một danh sách của lơp instances điều đó hành động giống từ điển mà chứa metadata về mỗi file quan tâm trong thư mục đó .
- Những người lập trình Old−school Pascal có thể thì thân thuộc với chúng , nhưng hầu như mọi người đưa tui một khỏang trắng khi tôi kể chúng rằng python hổ trở . một hàm lồng vào một hàm .
- getFileInfoClass có thể được gọi từ hàm trong , cái nó được định nghĩa listDirectory . Bạn không cần khai báo một giao diện hay bất cứ cái gì . chỉ định nghĩa hàm và gõ lệnh .