python-3.x - 如何在带有条件参数的函数中触发正确的条件语句
问题描述
我不知道如何问我的问题。我不确定我的问题是否特定于 Airflow,特定于下面共享的代码......或者只是我遗漏了一些明显的东西。
我正在开发一个 Airflow 项目,我正在导入以下模块:
https://airflow.readthedocs.io/en/latest/_modules/airflow/providers/google/cloud/hooks/gcs.html
这是我想从此模块使用的方法的代码:
def upload(self, bucket_name: str, object_name: str, filename: Optional[str] = None,
data: Optional[Union[str, bytes]] = None, mime_type: Optional[str] = None, gzip: bool = False,
encoding: str = 'utf-8') -> None:
"""
Uploads a local file or file data as string or bytes to Google Cloud Storage.
:param bucket_name: The bucket to upload to.
:type bucket_name: str
:param object_name: The object name to set when uploading the file.
:type object_name: str
:param filename: The local file path to the file to be uploaded.
:type filename: str
:param data: The file's data as a string or bytes to be uploaded.
:type data: str
:param mime_type: The file's mime type set when uploading the file.
:type mime_type: str
:param gzip: Option to compress local file or file data for upload
:type gzip: bool
:param encoding: bytes encoding for file data if provided as string
:type encoding: str
"""
client = self.get_conn()
bucket = client.bucket(bucket_name)
blob = bucket.blob(blob_name=object_name)
if filename and data:
raise ValueError("'filename' and 'data' parameter provided. Please "
"specify a single parameter, either 'filename' for "
"local file uploads or 'data' for file content uploads.")
elif filename:
if not mime_type:
mime_type = 'application/octet-stream'
if gzip:
filename_gz = filename + '.gz'
with open(filename, 'rb') as f_in:
with gz.open(filename_gz, 'wb') as f_out:
shutil.copyfileobj(f_in, f_out)
filename = filename_gz
blob.upload_from_filename(filename=filename,
content_type=mime_type)
if gzip:
os.remove(filename)
self.log.info('File %s uploaded to %s in %s bucket', filename, object_name, bucket_name)
elif data:
if not mime_type:
mime_type = 'text/plain'
if gzip:
if isinstance(data, str):
data = bytes(data, encoding)
out = BytesIO()
with gz.GzipFile(fileobj=out, mode="w") as f:
f.write(data)
data = out.getvalue()
blob.upload_from_string(data,
content_type=mime_type)
self.log.info('Data stream uploaded to %s in %s bucket', object_name, bucket_name)
else:
raise ValueError("'filename' and 'data' parameter missing. "
"One is required to upload to gcs.")
这基本上是调用此方法的一行代码:
conn.upload(bucket_name, object_name, data)
问题是,即使我正在传递一个名为的变量data
,我也可以看到upload_from_filename
当我想调用upload_from_string
.
我对 python 很陌生,但我在这里的理解是,如果我传递文件名参数,则upload_from_filename
应该调用该函数。如果我传递数据参数,则upload_from_string
应该调用该函数。
如果我没有传递任何东西,我会收到以下预期conn.upload(bucket_name, object_name)
的错误消息。filename' and 'data' parameter missing. "
根据我上面分享的代码,如果我想“切换”到该函数,我应该如何调用上传方法upload_from_string
?
解决方案
您正在传递位置参数。第三个位置参数是filename
,因此当您传递三个位置参数时,第三个参数转到filename
,所以conn.upload()
调用upload_from_filename()
。
要将数据作为关键字参数传递,您应该使用
conn.upload(bucket_name, object_name, data=data)
来自https://docs.python.org/3/glossary.html
有两种说法:
- 关键字参数:在函数调用中以标识符(例如
name=
)开头的参数或作为字典中的值传递的参数,以**
. 例如,在以下对 complex() 的调用中,3 和 5 都是关键字参数:
complex(real=3, imag=5)
complex(**{'real': 3, 'imag': 5})
- 位置参数:不是关键字参数的参数。位置参数可以出现在参数列表的开头和/或作为可迭代的元素传递
*
。例如,3 和 5 在以下调用中都是位置参数:
complex(3, 5)
complex(*(3, 5))
推荐阅读
- reactjs - Firebase 有时不会更新值
- assembly - A-20 线如何克服 Wrapping 问题
- azure - 如何使用 Azure CLI 创建 SQL 表?
- python - python - 如何计算一个序列在python的给定字符串中出现的次数?
- ios - 类型“UITextField”没有成员“textDidBeginEditingNotification”
- windows - Windows 中的打印屏幕
- python - 如何解压多个相同的元组
- r - 如何将具有不规则子列表的列表列表转换为数据框?
- java - 对编译器处理继承和方法调用感到困惑
- javascript - 具有多个 json 文件的 d3.js 队列