You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/source/guide.rst
+20-12
Original file line number
Diff line number
Diff line change
@@ -8,12 +8,13 @@ Why use PyFilesystem?
8
8
9
9
If you are comfortable using the Python standard library, you may be wondering; *why learn another API for working with files?*
10
10
11
-
The PyFilesystem API is generally simpler than the ``os`` and ``io`` modules. There are fewer ways to shoot yourself in the foot, the code tends to be more terse, and (arguably) more readable. This may be reason alone to use it, but there are other compelling reasons you should use ``import fs`` for even straightforward filesystem code.
11
+
The PyFilesystem API is generally simpler than the ``os`` and ``io`` modules -- there are fewer edge cases and less ways to shoot yourself in the foot. This may be reason alone to use it, but there are other compelling reasons you should use ``import fs`` for even straightforward filesystem code.
12
12
13
13
The abstraction offered by FS objects means that you can write code that is agnostic to where your files are physically located. For instance, if you wrote a function that searches a directory for duplicates files, it will work unaltered with a directory on your hard-drive, or in a zip file, on an FTP server, on Amazon S3, etc.
14
14
15
15
As long as an FS object exists for your chosen filesystem (or any data store that resembles a filesystem), you can use the same API. This means that you can defer the decision regarding where you store data to later. If you decide to store configuration in the *cloud*, it could be a single line change and not a major refactor.
16
16
17
+
17
18
PyFilesystem can also be beneficial for unit-testing; by swapping the OS filesystem with an in-memory filesystem, you can write tests without having to manage (or mock) file IO. And you can be sure that your code will work on Linux, MacOS, and Windows.
18
19
19
20
Opening Filesystems
@@ -84,7 +85,7 @@ This can be a useful debugging aid!
84
85
Closing Filesystems
85
86
~~~~~~~~~~~~~~~~~~~
86
87
87
-
FS objects have a ``close`` method (:meth:`fs.base.FS.close`) which will perform any required clean-up actions. For many filesystems (notably :class:`fs.osfs.OSFS`), the ``close`` method does very little, however, other filesystems may only finalize files or release resources once ``close()`` is called.
88
+
FS objects have a :meth:`fs.base.FS.close` methd which will perform any required clean-up actions. For many filesystems (notably :class:`fs.osfs.OSFS`), the ``close`` method does very little. Other filesystems may only finalize files or release resources once ``close()`` is called.
88
89
89
90
You can call ``close`` explicitly once you are finished using a filesystem. For example::
90
91
@@ -102,20 +103,23 @@ Using FS objects as a context manager is recommended as it will ensure every FS
102
103
Directory Information
103
104
~~~~~~~~~~~~~~~~~~~~~
104
105
105
-
Filesystem objects have a ``listdir`` method which is similar to ``os.listdir``; it takes a path to a directory and returns a list of file names. Here's an example::
106
+
Filesystem objects have a :meth:`fs.base.FS.listdir` method which is similar to ``os.listdir``; it takes a path to a directory and returns a list of file names. Here's an example::
106
107
107
108
>>> home_fs.listdir('/projects')
108
109
['fs', 'moya', 'README.md']
109
110
110
-
An alternative method exists for listing directories; if you call :meth:`fs.base.FS.scandir` it will return an *iterable* of :ref:`info` objects. Here's an example::
111
+
An alternative method exists for listing directories; :meth:`fs.base.FS.scandir` returns an *iterable* of :ref:`info` objects. Here's an example::
Info objects have a number of advantages over just a filename. For instance, you can know if a name references a directory with :attr:`fs.info.Info.is_dir`. Otherwise you would need to call :meth:`fs.base.FS.isdir` for each name in the directory, which may involve additional system calls (or request in the case of a network filesystem).
117
+
Info objects have a number of advantages over just a filename. For instance you can tell if an info object references a file or a directory with the :attr:`fs.info.Info.is_dir` attribute, without an additional system call. Info objects may also contain information such as size, modified time, etc. if you request it in the ``namespaces`` parameter.
118
+
117
119
118
-
The reason that ``scandir`` returns an iterable rather than a list, is that it can be more efficient to retrieve directory information in chunks if the directory is very large, or if the information must be retrieved over a network.
120
+
.. note::
121
+
122
+
The reason that ``scandir`` returns an iterable rather than a list, is that it can be more efficient to retrieve directory information in chunks if the directory is very large, or if the information must be retrieved over a network.
119
123
120
124
Additionally, FS objects have a :meth:`fs.base.FS.filterdir` method which extends ``scandir`` with the ability to filter directory contents by wildcard(s). Here's how you might find all the Python files in a directory:
121
125
@@ -165,23 +169,21 @@ Walking
165
169
166
170
Often you will need to scan the files in a given directory, and any sub-directories. This is known as *walking* the filesystem.
167
171
168
-
Here's how you would print the paths to all your Python files in your home-directory (and sub-directories)::
172
+
Here's how you would print the paths to all your Python files in your home directory::
169
173
170
174
>>> from fs import open_fs
171
175
>>> home_fs = open_fs('~/')
172
176
>>> for path in home_fs.walk.files(wildcards=['*.py']):
173
177
... print(path)
174
178
175
-
This might take a while to run if you have a lot of Python code!
176
-
177
-
The ``walk`` attribute on FS objects is instance of a :class:`fs.walk.BoundWalker`, which should be able to handle most directory walking requirements. It is designed to be customizable, if you do need to further tune the directory walk.
179
+
The ``walk`` attribute on FS objects is instance of a :class:`fs.walk.BoundWalker`, which should be able to handle most directory walking requirements.
178
180
179
181
See :ref:`walking` for more information on walking directories.
180
182
181
183
Working with Files
182
184
~~~~~~~~~~~~~~~~~~
183
185
184
-
You can open a file from a FS object with :meth:`fs.base.FS.open`, which is very similar to ``io.open`` in the standard library. Here's how you might open a file called reminder.txt in your home directory::
186
+
You can open a file from a FS object with :meth:`fs.base.FS.open`, which is very similar to ``io.open`` in the standard library. Here's how you might open a file called "reminder.txt" in your home directory::
185
187
186
188
>>> with open_fs('~/') as home_fs:
187
189
... with home_fs.open('reminder.txt') as reminder_file:
@@ -190,7 +192,7 @@ You can open a file from a FS object with :meth:`fs.base.FS.open`, which is very
190
192
191
193
In the case of a ``OSFS``, a standard file-like object will be returned. Other filesystems may return a different object supporting the same methods. For instance, :class:`fs.memoryfs.MemoryFS` will return a ``io.BytesIO`` object.
192
194
193
-
PyFilesystem also offers a number of shortcuts for common file related operations. For example, :meth:`fs.base.FS.getbytes` will return the file contents as a bytes object, and :meth:`fs.base.FS.gettext` will read unicode text. Using these methods is generally preferable to explicitly opening files, because the FS object may have an optimized implementation.
195
+
PyFilesystem also offers a number of shortcuts for common file related operations. For example, :meth:`fs.base.FS.getbytes` will return the file contents as a bytes, and :meth:`fs.base.FS.gettext` will read unicode text. Using these methods is generally preferable to explicitly opening files, as the FS object may have an optimized implementation.
194
196
195
197
Other *shortcut* methods are :meth:`fs.base.FS.setbin`, :meth:`fs.base.FS.setbytes`, :meth:`fs.base.FS.settext`.
196
198
@@ -213,3 +215,9 @@ Which is the equivalent to this, more verbose, code::
The :func:`fs.copy.copy_fs` and :func:`fs.copy.copy_dir` functions also accept a :class:`fs.walk.Walker` parameter, which can you use to filter the files that will be copied. For instance, if you only wanted back up your python files, you could use something like this::
0 commit comments