使用来自另一个脚本的参数启动 python 脚本,以编程方式设置 argparse 值
initiating python script with arguments from another script, setting argparse values programatically
我正在使用 python 程序包 (spotify_dl) 生成一些文件。我是通过命令行手动完成的:
spotify_dl -l spotify_playlist_link -o download_directory
现在我想从另一个 python 脚本中进行。
我查看了包代码并找到了主要功能,但我不知道如何 运行 使用我选择的参数的主要功能 - 在 python.
比如我想要的:
from spotify_dl import spotify_dl as sp_dl
if __name__=='__main__':
destination_dir = r'D:\some\folder\path'
playlists_url = ['url1','url2','url3',....]
for url in playlists_url:
sp_dl.spotify_dl(l=url,o=destination_dir)
为了更清楚,这里是 spotify_dl 主函数的实际代码:
#!/usr/bin/env python
import argparse
import json
import os
import sys
from logging import DEBUG
from pathlib import Path, PurePath
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
from spotify_dl.constants import VERSION
from spotify_dl.models import db, Song
from spotify_dl.scaffold import log, check_for_tokens
from spotify_dl.spotify import fetch_tracks, parse_spotify_url, validate_spotify_url, get_item_name
from spotify_dl.youtube import download_songs, default_filename, playlist_num_filename
def spotify_dl():
"""Main entry point of the script."""
parser = argparse.ArgumentParser(prog='spotify_dl')
parser.add_argument('-l', '--url', action="store",
help="Spotify Playlist link URL", type=str, required=True)
parser.add_argument('-o', '--output', type=str, action='store',
help='Specify download directory.', required=True)
parser.add_argument('-d', '--download', action='store_true',
help='Download using youtube-dl', default=True)
parser.add_argument('-f', '--format_str', type=str, action='store',
help='Specify youtube-dl format string.',
default='bestaudio/best')
parser.add_argument('-k', '--keep_playlist_order', default=False,
action='store_true',
help='Whether to keep original playlist ordering or not.')
parser.add_argument('-m', '--skip_mp3', action='store_true',
help='Don\'t convert downloaded songs to mp3')
parser.add_argument('-s', '--scrape', action="store",
help="Use HTML Scraper for YouTube Search", default=True)
parser.add_argument('-V', '--verbose', action='store_true',
help='Show more information on what''s happening.')
parser.add_argument('-v', '--version', action='store_true',
help='Shows current version of the program')
args = parser.parse_args()
if args.version:
print("spotify_dl v{}".format(VERSION))
exit(0)
db.connect()
db.create_tables([Song])
if os.path.isfile(os.path.expanduser('~/.spotify_dl_settings')):
with open(os.path.expanduser('~/.spotify_dl_settings')) as file:
config = json.loads(file.read())
for key, value in config.items():
if value and (value.lower() == 'true' or value.lower() == 't'):
setattr(args, key, True)
else:
setattr(args, key, value)
if args.verbose:
log.setLevel(DEBUG)
log.info('Starting spotify_dl')
log.debug('Setting debug mode on spotify_dl')
if not check_for_tokens():
exit(1)
sp = spotipy.Spotify(auth_manager=SpotifyClientCredentials())
log.debug('Arguments: {}'.format(args))
if args.url:
valid_item = validate_spotify_url(args.url)
if not valid_item:
sys.exit(1)
if args.output:
item_type, item_id = parse_spotify_url(args.url)
directory_name = get_item_name(sp, item_type, item_id)
save_path = Path(PurePath.joinpath(Path(args.output), Path(directory_name)))
save_path.mkdir(parents=True, exist_ok=True)
log.info("Saving songs to: {}".format(directory_name))
songs = fetch_tracks(sp, item_type, args.url)
if args.download is True:
file_name_f = default_filename
if args.keep_playlist_order:
file_name_f = playlist_num_filename
download_songs(songs, save_path, args.format_str, args.skip_mp3, args.keep_playlist_order, file_name_f)
if __name__ == '__main__':
spotify_dl()
到目前为止,我可以看到提到了 sys.argv,但也有一些评论反对使用它。
我想要的是一个清晰的方法,我可以 运行 在一个没有并发症的循环中。
你可以在这里使用subprocess
。
我没有尝试您的示例,因为我没有安装这些库,但这是一个简单的示例。
首先,一个名为 testpy.py
的简单命令行脚本具有以下内容:
import sys
import argparse
def check_arg(args=None):
parser = argparse.ArgumentParser(prog='Test',
description='Test',
epilog='Test')
parser.add_argument('-f', '--first',
help='First argument',
required='True')
results = parser.parse_args(args)
return (results.first)
def main():
with open('test.txt', 'a') as file:
file.write('Success, {}\n'.format(f))
if __name__ == '__main__':
f = check_arg(sys.argv[1:])
main()
这需要一个参数 f
并使用提供的任何参数导出一个文本文件 (test.txt)。
此脚本可以 运行 来自下一个脚本(将其另存为新脚本文件):
from subprocess import run, PIPE
args = ['python3', 'testpy.py', '-f', 'First input argument text']
res = run(args, stdout=PIPE, stderr=PIPE)
如果您 运行 执行此操作,您会看到文件 test.txt
将被导出并且从此脚本调用脚本 testpy.py
成功。
spotify_dl
设计的不好,我常用这个:
def parse_args(argv=None):
parser = argparse.ArgumentParser()
...
return parser.parse_args(argv)
def main(args):
# run your code
if __name__ == "__main__":
args = parse_args()
main(args)
然后您可以将第一个脚本导入另一个脚本并调用 main
函数:
from my_first_script import main
def a_function():
args = namedtuple("args", ("arg1", ...))("value1")
main(args)
但是您可以通过覆盖 sys.argv
:
来解决
if __name__=='__main__':
destination_dir = r'D:\some\folder\path'
playlists_url = ['url1','url2','url3',....]
for url in playlists_url:
sys.argv = [sys.executable, "-o", destination_dir, "-l", url]
sp_dl.spotify_dl()
我正在使用 python 程序包 (spotify_dl) 生成一些文件。我是通过命令行手动完成的: spotify_dl -l spotify_playlist_link -o download_directory
现在我想从另一个 python 脚本中进行。
我查看了包代码并找到了主要功能,但我不知道如何 运行 使用我选择的参数的主要功能 - 在 python.
比如我想要的:
from spotify_dl import spotify_dl as sp_dl
if __name__=='__main__':
destination_dir = r'D:\some\folder\path'
playlists_url = ['url1','url2','url3',....]
for url in playlists_url:
sp_dl.spotify_dl(l=url,o=destination_dir)
为了更清楚,这里是 spotify_dl 主函数的实际代码:
#!/usr/bin/env python
import argparse
import json
import os
import sys
from logging import DEBUG
from pathlib import Path, PurePath
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
from spotify_dl.constants import VERSION
from spotify_dl.models import db, Song
from spotify_dl.scaffold import log, check_for_tokens
from spotify_dl.spotify import fetch_tracks, parse_spotify_url, validate_spotify_url, get_item_name
from spotify_dl.youtube import download_songs, default_filename, playlist_num_filename
def spotify_dl():
"""Main entry point of the script."""
parser = argparse.ArgumentParser(prog='spotify_dl')
parser.add_argument('-l', '--url', action="store",
help="Spotify Playlist link URL", type=str, required=True)
parser.add_argument('-o', '--output', type=str, action='store',
help='Specify download directory.', required=True)
parser.add_argument('-d', '--download', action='store_true',
help='Download using youtube-dl', default=True)
parser.add_argument('-f', '--format_str', type=str, action='store',
help='Specify youtube-dl format string.',
default='bestaudio/best')
parser.add_argument('-k', '--keep_playlist_order', default=False,
action='store_true',
help='Whether to keep original playlist ordering or not.')
parser.add_argument('-m', '--skip_mp3', action='store_true',
help='Don\'t convert downloaded songs to mp3')
parser.add_argument('-s', '--scrape', action="store",
help="Use HTML Scraper for YouTube Search", default=True)
parser.add_argument('-V', '--verbose', action='store_true',
help='Show more information on what''s happening.')
parser.add_argument('-v', '--version', action='store_true',
help='Shows current version of the program')
args = parser.parse_args()
if args.version:
print("spotify_dl v{}".format(VERSION))
exit(0)
db.connect()
db.create_tables([Song])
if os.path.isfile(os.path.expanduser('~/.spotify_dl_settings')):
with open(os.path.expanduser('~/.spotify_dl_settings')) as file:
config = json.loads(file.read())
for key, value in config.items():
if value and (value.lower() == 'true' or value.lower() == 't'):
setattr(args, key, True)
else:
setattr(args, key, value)
if args.verbose:
log.setLevel(DEBUG)
log.info('Starting spotify_dl')
log.debug('Setting debug mode on spotify_dl')
if not check_for_tokens():
exit(1)
sp = spotipy.Spotify(auth_manager=SpotifyClientCredentials())
log.debug('Arguments: {}'.format(args))
if args.url:
valid_item = validate_spotify_url(args.url)
if not valid_item:
sys.exit(1)
if args.output:
item_type, item_id = parse_spotify_url(args.url)
directory_name = get_item_name(sp, item_type, item_id)
save_path = Path(PurePath.joinpath(Path(args.output), Path(directory_name)))
save_path.mkdir(parents=True, exist_ok=True)
log.info("Saving songs to: {}".format(directory_name))
songs = fetch_tracks(sp, item_type, args.url)
if args.download is True:
file_name_f = default_filename
if args.keep_playlist_order:
file_name_f = playlist_num_filename
download_songs(songs, save_path, args.format_str, args.skip_mp3, args.keep_playlist_order, file_name_f)
if __name__ == '__main__':
spotify_dl()
到目前为止,我可以看到提到了 sys.argv,但也有一些评论反对使用它。 我想要的是一个清晰的方法,我可以 运行 在一个没有并发症的循环中。
你可以在这里使用subprocess
。
我没有尝试您的示例,因为我没有安装这些库,但这是一个简单的示例。
首先,一个名为 testpy.py
的简单命令行脚本具有以下内容:
import sys
import argparse
def check_arg(args=None):
parser = argparse.ArgumentParser(prog='Test',
description='Test',
epilog='Test')
parser.add_argument('-f', '--first',
help='First argument',
required='True')
results = parser.parse_args(args)
return (results.first)
def main():
with open('test.txt', 'a') as file:
file.write('Success, {}\n'.format(f))
if __name__ == '__main__':
f = check_arg(sys.argv[1:])
main()
这需要一个参数 f
并使用提供的任何参数导出一个文本文件 (test.txt)。
此脚本可以 运行 来自下一个脚本(将其另存为新脚本文件):
from subprocess import run, PIPE
args = ['python3', 'testpy.py', '-f', 'First input argument text']
res = run(args, stdout=PIPE, stderr=PIPE)
如果您 运行 执行此操作,您会看到文件 test.txt
将被导出并且从此脚本调用脚本 testpy.py
成功。
spotify_dl
设计的不好,我常用这个:
def parse_args(argv=None):
parser = argparse.ArgumentParser()
...
return parser.parse_args(argv)
def main(args):
# run your code
if __name__ == "__main__":
args = parse_args()
main(args)
然后您可以将第一个脚本导入另一个脚本并调用 main
函数:
from my_first_script import main
def a_function():
args = namedtuple("args", ("arg1", ...))("value1")
main(args)
但是您可以通过覆盖 sys.argv
:
if __name__=='__main__':
destination_dir = r'D:\some\folder\path'
playlists_url = ['url1','url2','url3',....]
for url in playlists_url:
sys.argv = [sys.executable, "-o", destination_dir, "-l", url]
sp_dl.spotify_dl()