Phiên bản 14.0.0
của thư viện ứng dụng Python giới thiệu một tham số cấu hình bắt buộc mới có tên là use_proto_plus
. Tham số này sẽ chỉ định xem bạn muốn thư viện trả về thông báo proto-plus hay thông báo protobuf. Để biết thông tin chi tiết về cách đặt thông số này, hãy xem tài liệu về cấu hình.
Phần này mô tả các hệ quả về hiệu suất khi chọn loại thông báo cần sử dụng. Do đó, bạn nên đọc và tìm hiểu các lựa chọn để đưa ra quyết định sáng suốt. Tuy nhiên, nếu muốn nâng cấp lên phiên bản 14.0.0
mà không thay đổi mã, bạn có thể đặt use_proto_plus
thành True
để tránh làm hỏng các thay đổi về giao diện.
Thông báo proto-plus và protobuf
Trong phiên bản 10.0.0
, thư viện ứng dụng Python đã di chuyển sang một quy trình tạo mã mới tích hợp proto-plus như một cách để cải thiện tính tiện dụng của giao diện thông báo protobuf thông qua việc làm cho các quy trình đó hoạt động giống như các đối tượng Python gốc. Sự đánh đổi của điểm cải tiến này là proto-plus làm tăng chi phí hiệu suất.
Hiệu suất Proto+
Một trong những lợi ích cốt lõi của proto-plus là chuyển đổi thông báo protobuf và kiểu phổ biến thành các kiểu Python gốc thông qua một quy trình có tên là marshaling kiểu.
Quá trình so khớp xảy ra khi một trường được truy cập trên một thực thể thông báo proto-plus, cụ thể là khi một trường được đọc hoặc thiết lập, chẳng hạn như trong định nghĩa protobuf:
syntax = "proto3";
message Dog {
string name = 1;
}
Khi chuyển đổi định nghĩa này thành một lớp proto-plus, định nghĩa sẽ có dạng như sau:
import proto
class Dog(proto.Message):
name = proto.Field(proto.STRING, number=1)
Sau đó, bạn có thể khởi tạo lớp Dog
và truy cập vào trường name
của lớp đó giống như cách bạn thực hiện với bất kỳ đối tượng Python nào khác:
dog = Dog()
dog.name = "Scruffy"
print(dog.name)
Khi đọc và đặt trường name
, giá trị sẽ được chuyển đổi từ loại str
Python gốc sang loại string
để tương thích với thời gian chạy protobuf.
Trong bản phân tích đã tiến hành kể từ khi phát hành phiên bản 10.0.0
, chúng tôi đã xác định rằng thời gian dành để thực hiện các lượt chuyển đổi loại này có tác động đủ lớn đến hiệu suất. Điều quan trọng là việc cung cấp cho người dùng lựa chọn sử dụng thông báo protobuf.
Các trường hợp sử dụng thông báo proto-plus và protobuf
- Các trường hợp sử dụng thông báo Proto-plus
- Proto-plus cung cấp một số điểm cải tiến về công thái học so với thông báo protobuf, vì vậy, đây là loại thông báo lý tưởng để viết mã có thể bảo trì và đọc được. Vì hiển thị các đối tượng Python gốc nên các đối tượng này dễ sử dụng và dễ hiểu hơn.
- Các trường hợp sử dụng thông báo Protobuf
- Dùng protobuf cho các trường hợp sử dụng nhạy cảm về hiệu suất, đặc biệt là trong những ứng dụng cần xử lý nhanh các báo cáo lớn hoặc những ứng dụng tạo các yêu cầu thay đổi với số lượng lớn thao tác, chẳng hạn như với
BatchJobService
hoặcOfflineUserDataJobService
.
Thay đổi linh hoạt các loại thông báo
Sau khi chọn loại thông báo thích hợp cho ứng dụng, có thể bạn cần sử dụng loại khác cho một quy trình công việc cụ thể. Trong trường hợp này, bạn có thể dễ dàng linh hoạt chuyển đổi giữa hai loại này bằng cách sử dụng các tiện ích do thư viện ứng dụng cung cấp. Sử dụng cùng một lớp thông báo Dog
ở trên:
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)
Sự khác biệt về giao diện thông báo Protobuf
Giao diện proto-plus đã được ghi lại chi tiết, nhưng ở đây, chúng tôi sẽ làm nổi bật một số điểm khác biệt chính ảnh hưởng đến các trường hợp sử dụng phổ biến của thư viện ứng dụng Google Ads.
Chuyển đổi tuần tự byte
- Thông báo Proto-plus
serialized = type(campaign).serialize(campaign) deserialized = type(campaign).deserialize(serialized)
- Thông báo Protobuf
serialized = campaign.SerializeToString() deserialized = campaign.FromString(serialized)
Chuyển đổi tuần tự JSON
- Thông báo Proto-plus
serialized = type(campaign).to_json(campaign) deserialized = type(campaign).from_json(serialized)
- Thông báo Protobuf
from google.protobuf.json_format import MessageToJson, Parse serialized = MessageToJson(campaign) deserialized = Parse(serialized, campaign)
Mặt nạ trường
Phương thức trợ giúp mặt nạ trường do api-core cung cấp được thiết kế để sử dụng các thực thể thông báo protobuf. Vì vậy, khi sử dụng thông báo proto-plus, hãy chuyển đổi các thông báo đó thành thông báo protobuf để sử dụng trình trợ giúp:
- Thông báo Proto-plus
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)
- Thông báo Protobuf
from google.api_core.protobuf_helpers import field_mask campaign = client.get_type("Campaign") mask = field_mask(None, campaign)
Enum
Các enum được hiển thị bởi các thông điệp protoplus là các thực thể của loại enum
gốc của Python và do đó kế thừa một số phương thức tiện lợi.
Truy xuất loại enum
Khi sử dụng phương thức GoogleAdsClient.get_type
để truy xuất enum, các thông báo được trả về sẽ hơi khác nhau tuỳ thuộc vào việc bạn đang sử dụng thông báo proto-plus hay protobuf. Ví dụ:
- Thông báo Proto-plus
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
- Thông báo Protobuf
val = client.get_type("CampaignStatusEnum").PAUSED
Để việc truy xuất enum đơn giản hơn, có một thuộc tính tiện lợi trên các thực thể GoogleAdsClient
có giao diện nhất quán bất kể bạn đang sử dụng loại thông báo nào:
val = client.enums.CampaignStatusEnum.PAUSED
Truy xuất giá trị enum
Đôi khi, bạn nên biết giá trị hoặc mã trường của một enum nhất định, chẳng hạn như PAUSED
trên CampaignStatusEnum
tương ứng với 3
:
- Thông báo Proto-plus
campaign = client.get_type("Campaign") campaign.status = client.enums.CampaignStatusEnum.PAUSED # To read the value of campaign status print(campaign.status.value)
- Thông báo 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))
Truy xuất tên enum
Đôi khi, bạn nên biết tên của một trường enum. Ví dụ: khi
đọc các đối tượng từ API, bạn có thể muốn biết trạng thái chiến dịch
int 3
tương ứng với:
- Thông báo Proto-plus
campaign = client.get_type("Campaign") campaign.status = client.enums.CampaignStatusEnum.PAUSED # To read the name of campaign status print(campaign.status.name)
- Thông báo 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)
Các trường lặp lại
Như đã mô tả trong các tài liệu proto-plus, các trường lặp lại thường tương đương với danh sách đã nhập, tức là các trường này hoạt động gần như giống hệt với list
.
Thêm vào các trường vô hướng lặp lại
Khi thêm giá trị vào các trường loại vô hướng lặp lại, ví dụ: các trường string
hoặc int64
, giao diện sẽ giống nhau bất kể loại thông báo là gì:
- Thông báo Proto-plus
ad.final_urls.append("https://www.example.com")
- Thông báo Protobuf
ad.final_urls.append("https://www.example.com")
bao gồm cả mọi phương thức list
phổ biến khác, ví dụ extend
:
- Thông báo Proto-plus
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
- Thông báo Protobuf
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
Thêm các loại thông báo vào các trường lặp lại
Nếu trường lặp lại không phải là một kiểu vô hướng, thì hành vi khi thêm các trường đó vào các trường lặp lại sẽ hơi khác:
- Thông báo Proto-plus
frequency_cap = client.get_type("FrequencyCapEntry") frequency_cap.cap = 100 campaign.frequency_caps.append(frequency_cap)
- Thông báo Protobuf
# The add method initializes a message and adds it to the repeated field frequency_cap = campaign.frequency_caps.add() frequency_cap.cap = 100
Chỉ định các trường lặp lại
Đối với cả trường lặp lại vô hướng và không vô hướng, bạn có thể gán danh sách cho trường theo nhiều cách:
- Thông báo Proto-plus
# In proto-plus it's possible to use assignment. urls = ["https://www.example.com"] ad.final_urls = urls
- Thông báo 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
Thư không có nội dung
Đôi khi, bạn nên biết liệu một thực thể thông báo có chứa thông tin nào hoặc có tập hợp trường nào hay không.
- Thông báo Proto-plus
# When using proto-plus messages you can simply check the message for # truthiness. is_empty = bool(campaign) is_empty = not campaign
- Thông báo Protobuf
is_empty = campaign.ByteSize() == 0
Nội dung tin nhắn
Đối với cả thông báo proto-plus và protobuf, bạn nên sử dụng phương thức trợ giúp copy_from
trên GoogleAdsClient
:
client.copy_from(campaign, other_campaign)
Trường tin nhắn trống
Quy trình đặt các trường thông báo trống đều giống nhau bất kể bạn đang sử dụng loại thông báo nào. Bạn chỉ cần sao chép một tin nhắn trống vào trường đang đề cập đến. Xem mục Sao chép thư cũng như hướng dẫn về Trường thông báo trống. Dưới đây là ví dụ về cách đặt một trường tin nhắn trống:
client.copy_from(campaign.manual_cpm, client.get_type("ManualCpm"))
Tên trường là các từ dành riêng
Khi sử dụng thông điệp proto-plus, tên trường sẽ tự động xuất hiện với dấu gạch dưới ở giữa dấu gạch dưới nếu tên trường đó cũng là một từ dành riêng trong Python. Dưới đây là ví dụ về cách làm việc với một thực thể Asset
:
asset = client.get_type("Asset")
asset.type_ = client.enums.AssetTypeEnum.IMAGE
Danh sách đầy đủ các tên dành riêng được tạo trong mô-đun trình tạo gapic. Bạn cũng có thể truy cập vào tệp này theo phương thức lập trình.
Trước tiên, hãy cài đặt mô-đun:
python -m pip install gapic-generator
Sau đó, trong REPL hoặc tập lệnh Python:
import gapic.utils
print(gapic.utils.reserved_names.RESERVED_NAMES)
Sự hiện diện của trường
Vì các trường trên thực thể thông báo protobuf có giá trị mặc định, nên không phải lúc nào cũng trực quan để biết liệu một trường đã được đặt hay chưa.
- Thông báo Proto-plus
# Use the "in" operator. has_field = "name" in campaign
- Thông báo Protobuf
campaign = client.get_type("Campaign") # Determines whether "name" is set and not just an empty string. campaign.HasField("name")
Giao diện lớp Message
protobuf có phương thức HasField
xác định xem trường trên thông báo đã được đặt hay chưa, ngay cả khi trường đó được đặt thành giá trị mặc định.
Các phương thức thông báo Protobuf
Giao diện thông báo protobuf bao gồm một số phương thức tiện lợi không thuộc giao diện proto-plus. Tuy nhiên, bạn có thể dễ dàng truy cập vào các phương thức đó bằng cách chuyển đổi thông báo protobuf thành thông báo protobuf tương ứng:
# 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())
Công cụ theo dõi lỗi
Nếu bạn có bất kỳ thắc mắc nào về những thay đổi này hoặc bất kỳ vấn đề nào khi chuyển sang phiên bản 14.0.0
của thư viện, hãy báo cáo vấn đề trên công cụ theo dõi của chúng tôi.