You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Python中基于CLI参数的函数改为接收参数的函数

解决方案:分离命令行解析与业务逻辑,构造模拟参数对象

核心思路是把依赖命令行args的代码拆分为纯业务逻辑函数和参数适配层,既保留原命令行功能,又能让其他函数直接调用。

步骤1:重构核心业务函数,接收显式参数

把原来依赖args对象的函数改成接收明确的业务参数,摆脱对命令行解析的依赖:

重构认证函数get_authenticated_service

原来的函数依赖args,现在改成接收具体的OAuth参数,同时构造一个模拟的flags对象满足run_flow的要求:

from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from collections import namedtuple

def get_authenticated_service(client_secrets_file, scopes, auth_host_name='localhost', auth_host_port=[8080, 8090], noauth_local_webserver=False):
    # 用namedtuple构造模拟的flags对象,匹配run_flow需要的参数结构
    MockFlags = namedtuple('MockFlags', [
        'client_secrets_file', 'scopes', 'auth_host_name', 
        'auth_host_port', 'noauth_local_webserver'
    ])
    flags = MockFlags(
        client_secrets_file=client_secrets_file,
        scopes=scopes,
        auth_host_name=auth_host_name,
        auth_host_port=auth_host_port,
        noauth_local_webserver=noauth_local_webserver
    )
    
    flow = InstalledAppFlow.from_client_secrets_file(flags.client_secrets_file, flags.scopes)
    credentials = flow.run_console(args=flags)
    return build('youtube', 'v3', credentials=credentials)

重构上传函数initialize_upload

让它只接收上传视频所需的业务参数,完全脱离命令行解析:

from googleapiclient.http import MediaFileUpload

def initialize_upload(youtube, file_path, title, description, tags, category_id, privacy_status='private'):
    body = {
        'snippet': {
            'title': title,
            'description': description,
            'tags': tags,
            'categoryId': category_id
        },
        'status': {
            'privacyStatus': privacy_status
        }
    }

    media = MediaFileUpload(file_path, chunksize=-1, resumable=True)
    request = youtube.videos().insert(
        part='snippet,status',
        body=body,
        media_body=media
    )

    # 原有的可恢复上传逻辑(保持不变)
    response = None
    while response is None:
        status, response = request.next_chunk()
        if status:
            print(f"Uploaded {int(status.progress() * 100)}%")
    print("Upload Complete!")

步骤2:新增编程式调用入口

封装一个顶层函数,供其他Python函数直接调用:

def upload_youtube_video(
    client_secrets_file,
    scopes,
    file_path,
    title,
    description,
    tags,
    category_id,
    privacy_status='private',
    auth_host_name='localhost',
    auth_host_port=[8080, 8090],
    noauth_local_webserver=False
):
    youtube = get_authenticated_service(
        client_secrets_file=client_secrets_file,
        scopes=scopes,
        auth_host_name=auth_host_name,
        auth_host_port=auth_host_port,
        noauth_local_webserver=noauth_local_webserver
    )
    initialize_upload(
        youtube=youtube,
        file_path=file_path,
        title=title,
        description=description,
        tags=tags,
        category_id=category_id,
        privacy_status=privacy_status
    )

步骤3:保留原命令行功能

在__main__块中解析命令行参数,然后调用新的顶层函数,兼容原有使用方式:

import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--client-secrets-file', required=True, help='客户端密钥文件路径')
    parser.add_argument('--scopes', default='https://www.googleapis.com/auth/youtube.upload', help='OAuth权限范围')
    parser.add_argument('--file', required=True, help='视频文件路径')
    parser.add_argument('--title', required=True, help='视频标题')
    parser.add_argument('--description', default='', help='视频描述')
    parser.add_argument('--tags', nargs='+', default=[], help='视频标签')
    parser.add_argument('--category-id', default='22', help='视频分类ID')
    parser.add_argument('--privacy-status', default='private', help='隐私状态:public/private/unlisted')
    parser.add_argument('--noauth-local-webserver', action='store_true', help='不启动本地web服务器,使用控制台授权')
    
    args = parser.parse_args()

    upload_youtube_video(
        client_secrets_file=args.client_secrets_file,
        scopes=args.scopes,
        file_path=args.file,
        title=args.title,
        description=args.description,
        tags=args.tags,
        category_id=args.category_id,
        privacy_status=args.privacy_status,
        noauth_local_webserver=args.noauth_local_webserver
    )

优势说明

  • 业务逻辑与命令行解析完全解耦,upload_youtube_video可以被任何其他Python函数直接调用,传入明确参数即可。
  • 用namedtuple模拟flags对象,比包装函数更清晰,明确知道需要哪些参数,避免黑箱调用。
  • 完全保留原命令行功能,兼容两种使用场景。

内容的提问来源于stack exchange,提问作者icicleking

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 11:52:41