We will learn the following while working on our Python Script:
Creating files with Python
Creating a single file
Here’s a one-liner for creating a file with Python.
<span>open</span><span>(</span><span>'</span><span>hello_world.txt</span><span>'</span><span>,</span><span>'</span><span>w</span><span>'</span><span>)</span><span>open</span><span>(</span><span>'</span><span>hello_world.txt</span><span>'</span><span>,</span><span>'</span><span>w</span><span>'</span><span>)</span>open('hello_world.txt','w')
Enter fullscreen mode Exit fullscreen mode
This single statement creates hello_world.txt
, but we don’t want fixed file names, do we?
The question is, how to conveniently provide input to the script to create a file with Python.
We can use a variable for storing the name of the file, like this…
<span>filename</span> <span>=</span> <span>"</span><span>hello_world.txt</span><span>"</span><span>open</span><span>(</span><span>filename</span><span>,</span> <span>'</span><span>w</span><span>'</span><span>)</span><span>filename</span> <span>=</span> <span>"</span><span>hello_world.txt</span><span>"</span> <span>open</span><span>(</span><span>filename</span><span>,</span> <span>'</span><span>w</span><span>'</span><span>)</span>filename = "hello_world.txt" open(filename, 'w')
Enter fullscreen mode Exit fullscreen mode
But this will be a mess if we want to create multiple files with Python, as each time we want to create a file, we would need to update filename
variable manually which ain’t so cool.
Creating multiple files
The solution to the above problem is, making a list of filenames.
<span>filenames</span> <span>=</span> <span>[</span><span>'</span><span>hello_world.txt</span><span>'</span><span>,</span> <span>'</span><span>random_file.txt</span><span>'</span><span>,</span> <span>'</span><span>lol.txt</span><span>'</span><span>]</span><span>for</span> <span>filename</span> <span>in</span> <span>filenames</span><span>:</span><span>open</span><span>(</span><span>filename</span><span>,</span> <span>'</span><span>w</span><span>'</span><span>)</span><span>filenames</span> <span>=</span> <span>[</span><span>'</span><span>hello_world.txt</span><span>'</span><span>,</span> <span>'</span><span>random_file.txt</span><span>'</span><span>,</span> <span>'</span><span>lol.txt</span><span>'</span><span>]</span> <span>for</span> <span>filename</span> <span>in</span> <span>filenames</span><span>:</span> <span>open</span><span>(</span><span>filename</span><span>,</span> <span>'</span><span>w</span><span>'</span><span>)</span>filenames = ['hello_world.txt', 'random_file.txt', 'lol.txt'] for filename in filenames: open(filename, 'w')
Enter fullscreen mode Exit fullscreen mode
This is MUCH BETTER 🤩! But wait, It’s only good for one-time use . What if we want to make more files later in a single go?
Then we would have to update the filenames
list again and again.
Providing filenames from the command line
For this fix, we can provide values (filenames) from the command line! We only need to make two changes in our existing code.
Add from sys import argv
and use the value of argv
with for filenames
.
<span>from</span> <span>sys</span> <span>import</span> <span>argv</span><span>filenames</span> <span>=</span> <span>argv</span><span>[</span><span>1</span><span>:]</span> <span># Ignore the first element (script file) </span><span>for</span> <span>filename</span> <span>in</span> <span>filenames</span><span>:</span><span>open</span><span>(</span><span>filename</span><span>,</span> <span>'</span><span>w</span><span>'</span><span>)</span><span>from</span> <span>sys</span> <span>import</span> <span>argv</span> <span>filenames</span> <span>=</span> <span>argv</span><span>[</span><span>1</span><span>:]</span> <span># Ignore the first element (script file) </span> <span>for</span> <span>filename</span> <span>in</span> <span>filenames</span><span>:</span> <span>open</span><span>(</span><span>filename</span><span>,</span> <span>'</span><span>w</span><span>'</span><span>)</span>from sys import argv filenames = argv[1:] # Ignore the first element (script file) for filename in filenames: open(filename, 'w')
Enter fullscreen mode Exit fullscreen mode
This seems to work just fine but there’s a nasty bug in it.
If the file already exists, it will wipe the whole file’s contents. Thanks to the file access mode 'w'
(write mode) which we used.
The fix is very simple. We just need to replace 'w'
with 'a'
(append mode) which will ignore the files which already exist and create new ones if they don’t.
<span>from</span> <span>sys</span> <span>import</span> <span>argv</span><span>filenames</span> <span>=</span> <span>argv</span><span>[</span><span>1</span><span>:]</span> <span># Ignore the first element (script file) </span><span>for</span> <span>filename</span> <span>in</span> <span>filenames</span><span>:</span><span>open</span><span>(</span><span>filename</span><span>,</span> <span>'</span><span>a</span><span>'</span><span>)</span> <span># Using append mode now </span><span>from</span> <span>sys</span> <span>import</span> <span>argv</span> <span>filenames</span> <span>=</span> <span>argv</span><span>[</span><span>1</span><span>:]</span> <span># Ignore the first element (script file) </span> <span>for</span> <span>filename</span> <span>in</span> <span>filenames</span><span>:</span> <span>open</span><span>(</span><span>filename</span><span>,</span> <span>'</span><span>a</span><span>'</span><span>)</span> <span># Using append mode now </span>from sys import argv filenames = argv[1:] # Ignore the first element (script file) for filename in filenames: open(filename, 'a') # Using append mode now
Enter fullscreen mode Exit fullscreen mode
Testing our script
I saved the script as touch.py
here’s the execution…
Creating multiple files with our Python script
Existing files remain unchanged, YAY!
Touch command
Our script is GOOOOOODDD!!!
But there’s still one thing we can add to make it behave more like touch command, that is, updating a file’s access and modified time.
For the sake of keeping things simple, we will just update the modified time of the file.
Getting the access time and modified time of a file
The os
module in Python has a stat
function that performs a stat system call (runs a stat command behind the scenes) and returns the result in an accessible way.
<span>from</span> <span>os</span> <span>import</span> <span>stat</span><span>st_info</span> <span>=</span> <span>stat</span><span>(</span><span>filename</span><span>)</span><span>access_time</span> <span>=</span> <span>st_info</span><span>.</span><span>st_atime</span><span>modified_time</span> <span>=</span> <span>st_info</span><span>.</span><span>st_mtime</span><span>from</span> <span>os</span> <span>import</span> <span>stat</span> <span>st_info</span> <span>=</span> <span>stat</span><span>(</span><span>filename</span><span>)</span> <span>access_time</span> <span>=</span> <span>st_info</span><span>.</span><span>st_atime</span> <span>modified_time</span> <span>=</span> <span>st_info</span><span>.</span><span>st_mtime</span>from os import stat st_info = stat(filename) access_time = st_info.st_atime modified_time = st_info.st_mtime
Enter fullscreen mode Exit fullscreen mode
We can use the result st_info
which contains the status of the file including the access and modified time for modifying the file.
Getting the current time
time
function in the time
module returns the current time which we can directly use in our script for modifying the files with our script.
<p><span>from</span> <span>time</span> <span>import</span> <span>time</span><br> <span>current_time</span> <span>=</span> <span>time</span><span>()</span> <span># current time in seconds (since Epoch)<br> </span></p><p><span>from</span> <span>time</span> <span>import</span> <span>time</span><br> <span>current_time</span> <span>=</span> <span>time</span><span>()</span> <span># current time in seconds (since Epoch)<br> </span></p>
from time import time
current_time = time() # current time in seconds (since Epoch)
Enter fullscreen mode Exit fullscreen mode
Updating Access and Modified time in a file
The os
module also has a function for updating this access and modified time called utime
.
Here’s how this can be done,
<p><span>from</span> <span>os</span> <span>import</span> <span>utime</span></p><p><span># if the second argument isn't passed, it will set the access</span></p><h1 id="wznav_10"> <a href="https://blogs.ink/?golink=aHR0cHM6Ly9kZXYudG8vL2dhZ2FuZ3VseWFuaS9jcmVhdGluZy1maWxlcy13aXRoLXB5dGhvbi1hbmQtbWltaWNraW5nLXRoZS10b3VjaC1jb21tYW5kLWhobSNhbmQtbW9kaWZpZWQtdGltZS10by1jdXJyZW50LXRpbWU=" target="_blank" rel="nofollow"> </a> and modified time to current time </h1><p><br> <span>utime</span><span>(</span><span>filename</span><span>)</span></p><p><span># for setting our custom access and modified time<br> </span><span>utime</span><span>(</span><span>filename</span><span>,</span> <span>(</span><span>access_time</span><span>,</span> <span>current_time</span><span>))</span></p><p><span>from</span> <span>os</span> <span>import</span> <span>utime</span></p> <p><span># if the second argument isn't passed, it will set the access</span></p> <h1 id="wznav_10"> <a href="https://blogs.ink/?golink=aHR0cHM6Ly9kZXYudG8vL2dhZ2FuZ3VseWFuaS9jcmVhdGluZy1maWxlcy13aXRoLXB5dGhvbi1hbmQtbWltaWNraW5nLXRoZS10b3VjaC1jb21tYW5kLWhobSNhbmQtbW9kaWZpZWQtdGltZS10by1jdXJyZW50LXRpbWU=" target="_blank" rel="nofollow"> </a> and modified time to current time </h1> <p><br> <span>utime</span><span>(</span><span>filename</span><span>)</span></p> <p><span># for setting our custom access and modified time<br> </span><span>utime</span><span>(</span><span>filename</span><span>,</span> <span>(</span><span>access_time</span><span>,</span> <span>current_time</span><span>))</span></p>
from os import utime
# if the second argument isn't passed, it will set the access
and modified time to current time
utime(filename)# for setting our custom access and modified time
utime(filename, (access_time, current_time))
Enter fullscreen mode Exit fullscreen mode
Implementing the Touch Command
Now, we can finally put together everything we have done so far in one final script.
<p><span>from</span> <span>sys</span> <span>import</span> <span>argv</span><br> <span>from</span> <span>time</span> <span>import</span> <span>time</span><br> <span>from</span> <span>os</span> <span>import</span> <span>utime</span><span>,</span> <span>stat</span></p><p><span>for</span> <span>name</span> <span>in</span> <span>argv</span><span>[</span><span>1</span><span>:]:</span><br> <span>open</span><span>(</span><span>name</span><span>,</span> <span>'</span><span>a</span><span>'</span><span>)</span><br> <span>st_info</span> <span>=</span> <span>stat</span><span>(</span><span>name</span><span>)</span> <span># Storing file status<br> </span> <span># setting access time with file's access time (no change)<br> </span> <span># setting modified time with current time of the system)<br> </span> <span>utime</span><span>(</span><span>name</span><span>,</span> <span>(</span><span>st_info</span><span>.</span><span>st_atime</span><span>,</span> <span>time</span><span>()))</span></p><p><span>from</span> <span>sys</span> <span>import</span> <span>argv</span><br> <span>from</span> <span>time</span> <span>import</span> <span>time</span><br> <span>from</span> <span>os</span> <span>import</span> <span>utime</span><span>,</span> <span>stat</span></p> <p><span>for</span> <span>name</span> <span>in</span> <span>argv</span><span>[</span><span>1</span><span>:]:</span><br> <span>open</span><span>(</span><span>name</span><span>,</span> <span>'</span><span>a</span><span>'</span><span>)</span><br> <span>st_info</span> <span>=</span> <span>stat</span><span>(</span><span>name</span><span>)</span> <span># Storing file status<br> </span> <span># setting access time with file's access time (no change)<br> </span> <span># setting modified time with current time of the system)<br> </span> <span>utime</span><span>(</span><span>name</span><span>,</span> <span>(</span><span>st_info</span><span>.</span><span>st_atime</span><span>,</span> <span>time</span><span>()))</span></p>
from sys import argv
from time import time
from os import utime, statfor name in argv[1:]:
open(name, 'a')
st_info = stat(name) # Storing file status
# setting access time with file's access time (no change)
# setting modified time with current time of the system)
utime(name, (st_info.st_atime, time()))
Enter fullscreen mode Exit fullscreen mode
Result
Finally, It’s time we use the script for creating files and stuff.
Multiple files created Succesfully!
Our script successfully updates the modified time of existing file!!
That’s it! Our script makes multiple files and mimics the touch command as it sets the modified time!
You can tweak it and add more features to make it a complete touch command clone.
原文链接:Creating files with Python and mimicking the “touch command”
暂无评论内容