版本
14.0.0
引入了一个新的必需配置参数
名为 use_proto_plus
,用于指定是否希望库返回
proto-plus messages 或
protobuf 消息。如需详细了解
如何设置此参数,请参阅配置文档。
本部分介绍了选择
因此我们建议您阅读并理解
从而做出明智的决策。但是,如果您希望
在不更改代码的情况下升级到版本14.0.0
;您可以设置
将 use_proto_plus
设置为 True
,以避免破坏性接口更改。
Proto-plus 消息与 protobuf 消息
在版本 10.0.0
中,Python 客户端库迁移到了新的代码生成器
集成了
proto-plus,作为改进
通过使 protobuf 消息接口的行为更便于用户操作,
例如原生 Python 对象这种改进的代价是,proto-plus
会产生性能开销
Proto+ 性能
proto-plus 的核心优势之一是,它可以将 protobuf 消息 和知名类型 通过名为“type”的进程 编组。
在 proto-plus 消息实例上访问字段时,会发生编组, 具体而言,在读取或设置字段时,例如在 protobuf 定义:
syntax = "proto3";
message Dog {
string name = 1;
}
当此定义转换为 proto-plus 类时,其内容将如下所示: 如下所示:
import proto
class Dog(proto.Message):
name = proto.Field(proto.STRING, number=1)
然后,您可以初始化 Dog
类并访问其 name
字段,就像
任何其他 Python 对象:
dog = Dog()
dog.name = "Scruffy"
print(dog.name)
读取和设置 name
字段时,该值将从原生
将 Python str
类型转换为 string
类型,因此
该值与 protobuf 运行时兼容。
自 10.0.0
版发布以来,我们所做的分析如下:
确定了进行这些类型转化所花费的时间足以
对性能的影响,务必要向用户提供使用 protobuf
消息。
proto-plus 和 protobuf 消息的用例
- Proto-plus 信息应用场景
- 与 protobuf 消息相比,Proto-plus 提供了许多人体工程学改进, 因此非常适合编写可维护、可读的代码。因为它们公开了 原生 Python 对象,它们更易于使用和理解。
- Protobuf 消息用例
- 针对对性能要求较高的应用场景(尤其是在应用中)使用 protobuf
需要快速处理大型报告,或使用
大量操作,例如
BatchJobService
或OfflineUserDataJobService
。
动态更改消息类型
为应用选择适当的消息类型后,您可能会发现
您需要对特定工作流使用另一种类型。在此例中是
使用
客户端库。使用与上文相同的 Dog
消息类:
from google.ads.googleads import util
# Proto-plus message type
dog = Dog()
# Protobuf message type
dog = util.convert_proto_plus_to_protobuf(dog)
# Back to proto-plus message type
dog = util.convert_protobuf_to_proto_plus(dog)
Protobuf 消息接口差异
proto-plus 接口记录在 details,但在此我们将重点介绍 影响 Google Ads 客户端常见用例的一些关键差异 库。
字节序列化
- Proto+ 消息
serialized = type(campaign).serialize(campaign) deserialized = type(campaign).deserialize(serialized)
- Protobuf 消息
serialized = campaign.SerializeToString() deserialized = campaign.FromString(serialized)
JSON 序列化
- Proto+ 消息
serialized = type(campaign).to_json(campaign) deserialized = type(campaign).from_json(serialized)
- Protobuf 消息
from google.protobuf.json_format import MessageToJson, Parse serialized = MessageToJson(campaign) deserialized = Parse(serialized, campaign)
字段掩码
此字段的掩码辅助方法 api-core 旨在使用 protobuf 消息实例。因此在使用 proto-plus 消息时,将其转换为 protobuf 消息来利用帮助程序:
- Proto+ 消息
from google.api_core.protobuf_helpers import field_mask campaign = client.get_type("Campaign") protobuf_campaign = util.convert_proto_plus_to_protobuf(campaign) mask = field_mask(None, protobuf_campaign)
- Protobuf 消息
from google.api_core.protobuf_helpers import field_mask campaign = client.get_type("Campaign") mask = field_mask(None, campaign)
枚举
proto-plus 消息公开的枚举是 Python 的原生代码实例,
enum
类型,因此
继承许多便捷方法。
枚举类型检索
使用 GoogleAdsClient.get_type
方法检索枚举时,消息
具体取决于您使用的是
proto-plus 或 protobuf 消息。例如:
- Proto+ 消息
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
- Protobuf 消息
val = client.get_type("CampaignStatusEnum").PAUSED
为了简化枚举的检索,
GoogleAdsClient
实例具有一致的接口,无论
消息类型:
val = client.enums.CampaignStatusEnum.PAUSED
枚举值检索
有时,对于给定的枚举,了解特定枚举的值或字段 ID 非常有用
例如,CampaignStatusEnum
上的 PAUSED
对应于 3
:
- Proto+ 消息
campaign = client.get_type("Campaign") campaign.status = client.enums.CampaignStatusEnum.PAUSED # To read the value of campaign status print(campaign.status.value)
- Protobuf 消息
campaign = client.get_type("Campaign") status_enum = client.enums.CampaignStatusEnum campaign.status = status_enum.PAUSED # To read the value of campaign status print(status_enum.CampaignStatus.Value(campaign.status))
枚举名称检索
有时,了解枚举字段的名称会很有用。例如,当
从 API 读取对象时,您可能希望了解
整数 3
对应于:
- Proto+ 消息
campaign = client.get_type("Campaign") campaign.status = client.enums.CampaignStatusEnum.PAUSED # To read the name of campaign status print(campaign.status.name)
- Protobuf 消息
campaign = client.get_type("Campaign") status_enum = client.enums.CampaignStatusEnum # Sets the campaign status to the int value for PAUSED campaign.status = status_enum.PAUSED # To read the name of campaign status status_enum.CampaignStatus.Name(campaign.status)
重复字段
如 proto-plus
文档、
重复字段通常等同于类型化列表,也就是说,
其行为与 list
几乎完全相同。
附加到重复的标量字段
向重复标量添加值时
type 字段,例如
string
或 int64
字段,无论消息如何,接口都相同
类型:
- Proto+ 消息
ad.final_urls.append("https://www.example.com")
- Protobuf 消息
ad.final_urls.append("https://www.example.com")
这也包括所有其他常见的 list
方法,例如 extend
:
- Proto+ 消息
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
- Protobuf 消息
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
将消息类型附加到重复字段
如果重复字段不是标量 type:将它们添加到 重复字段略有不同:
- Proto+ 消息
frequency_cap = client.get_type("FrequencyCapEntry") frequency_cap.cap = 100 campaign.frequency_caps.append(frequency_cap)
- Protobuf 消息
# The add method initializes a message and adds it to the repeated field frequency_cap = campaign.frequency_caps.add() frequency_cap.cap = 100
分配重复字段
对于标量和非标量重复字段,您都可以将列表分配给 字段:
- Proto+ 消息
# In proto-plus it's possible to use assignment. urls = ["https://www.example.com"] ad.final_urls = urls
- Protobuf 消息
# Protobuf messages do not allow assignment, but you can replace the # existing list using slice syntax. urls = ["https://www.example.com"] ad.final_urls[:] = urls
空白消息
有时了解消息实例是否包含 信息或设置了任何字段。
- Proto+ 消息
# When using proto-plus messages you can simply check the message for # truthiness. is_empty = bool(campaign) is_empty = not campaign
- Protobuf 消息
is_empty = campaign.ByteSize() == 0
消息文案
对于 proto-plus 和 protobuf 消息,我们建议使用 copy_from
对 GoogleAdsClient
调用辅助方法:
client.copy_from(campaign, other_campaign)
消息字段为空
设置空白消息字段的过程是相同的,无论 消息类型。只需将一个空消息复制到该字段中即可 问题。请参阅邮件副本部分和空白邮件 字段指南。这里的示例说明了 设置空白消息字段:
client.copy_from(campaign.manual_cpm, client.get_type("ManualCpm"))
采用保留字的字段名称
使用 proto-plus 消息时,字段名称会自动与
如果名称在 Python 中也是保留字,则使用尾随下划线。这里有
使用 Asset
实例的示例:
asset = client.get_type("Asset")
asset.type_ = client.enums.AssetTypeEnum.IMAGE
名称 是在 Gapic generator模块。它可以 也可以以编程方式访问
首先,安装模块:
python -m pip install gapic-generator
然后,在 Python REPL 或脚本中执行以下操作:
import gapic.utils
print(gapic.utils.reserved_names.RESERVED_NAMES)
字段存在
由于 protobuf 消息实例上的字段具有默认值, 始终直观地了解是否设置了某个字段。
- Proto+ 消息
# Use the "in" operator. has_field = "name" in campaign
- Protobuf 消息
campaign = client.get_type("Campaign") # Determines whether "name" is set and not just an empty string. campaign.HasField("name")
protobuf
Message
类接口有一个 HasField
方法,用于确定
消息,即使它被设为默认值。
Protobuf 消息方法
protobuf 消息接口包含一些便捷方法, proto-plus 接口的一部分;但您也可以轻松 将 proto-plus 消息转换为其 protobuf 副本:
# Accessing the ListFields method
protobuf_campaign = util.convert_protobuf_to_proto_plus(campaign)
print(campaign.ListFields())
# Accessing the Clear method
protobuf_campaign = util.convert_protobuf_to_proto_plus(campaign)
print(campaign.Clear())
问题跟踪器
如果您对这些变化有任何疑问,或者对迁移到
14.0.0
版,请提交
问题
智能设备。