Thông báo Protobuf

Với tham số cấu hình use_proto_plus, bạn có thể chỉ định xem bạn muốn thư viện trả về tin nhắn proto-plus hay tin nhắn 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ả những tác động đến hiệu suất khi chọn loại thông báo sẽ sử dụng. Do đó, bạn nên đọc và hiểu các lựa chọn để đưa ra quyết định sáng suốt.

Thông báo proto-plus so với thông báo protobuf

Quy trình tạo mã tích hợp proto-plus để cải thiện tính công thái học của giao diện thông báo protobuf bằng cách làm cho các giao diện này hoạt động giống như các đối tượng Python gốc. Tuy nhiên, điều này có nghĩa là việc sử dụng proto-plus sẽ làm tăng mức hao tổn hiệu suất.

Hiệu suất của Proto-plus

Một trong những lợi ích cốt lõi của proto-plus là chuyển đổi thông điệp protobufcác loại đã biết thành các loại Python gốc thông qua một quy trình có tên là sắp xếp loại.

Việc điều phối 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 đặt, ví dụ: trong định nghĩa protobuf:

syntax = "proto3";

message Dog {
  string name = 1;
}

Khi được chuyển đổi thành lớp proto-plus, định nghĩa này 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 chạy lớp Dog và truy cập vào trường name của lớp này như đối với mọi đối tượng Python khác:

dog = Dog()
dog.name = "Scruffy"
print(dog.name)

Khi đọc và đặt trường name, giá trị được chuyển đổi từ loại str Python gốc sang loại string để giá trị tương thích với thời gian chạy protobuf.

Dựa trên kết quả phân tích hiệu suất, chúng tôi xác định rằng thời gian 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 để người dùng quyết định có nên sử dụng thông điệp protobuf hay không, dựa trên nhu cầu của họ.

Các trường hợp sử dụng cho thông điệp 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ề mặt công thái học so với thông điệp protobuf, vì vậy, chúng rất lý tưởng để viết mã dễ đọc và dễ bảo trì. 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
Sử dụng protobuf cho các trường hợp sử dụng nhạy cảm về hiệu suất, cụ thể là trong các ứng dụng cần xử lý nhanh các báo cáo lớn hoặc tạo các yêu cầu thay đổi với số lượng lớn thao tác, ví dụ: với BatchJobService hoặc OfflineUserDataJobService.

Thay đổi linh động các loại thông báo

Sau khi chọn loại thông báo phù hợp cho ứng dụng, bạn có thể thấy mình cần sử dụng loại thông báo 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 chuyển đổi linh hoạt giữa hai loại này bằ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 tin nhắn Protobuf

Giao diện proto-plus được ghi lại chi tiết, nhưng ở đây chúng ta 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 điệp Protobuf
serialized = campaign.SerializeToString()
deserialized = campaign.FromString(serialized)

Tuần tự hoá JSON

Thông báo proto-plus
serialized = type(campaign).to_json(campaign)
deserialized = type(campaign).from_json(serialized)
Thông điệp 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ình 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 các 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 điệp Protobuf
from google.api_core.protobuf_helpers import field_mask

campaign = client.get_type("Campaign")
mask = field_mask(None, campaign)

Enum

Các enum do thông báo proto-plus hiển thị 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 thuận tiện.

Truy xuất loại enum

Khi sử dụng phương thức GoogleAdsClient.get_type để truy xuất enum, 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 điệp Protobuf
val = client.get_type("CampaignStatusEnum").PAUSED

Để 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ã nhận dạng trường của một enum nhất định, ví dụ: 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 điệp 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 cần biết tên của 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 mà int 3 tương ứng:

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 điệp 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)

Trường lặp lại

Như mô tả trong tài liệu về proto-plus, các trường lặp lại thường tương đương với danh sách đã nhập, nghĩa là các trường này hoạt động gần giống với list.

Nối các giá trị 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 scala lặp lại, chẳng hạn như trường string hoặc int64, giao diện sẽ giống nhau bất kể loại thông báo:

Thông báo proto-plus
ad.final_urls.append("https://www.example.com")
Thông điệp Protobuf
ad.final_urls.append("https://www.example.com")

Điều này cũng bao gồm tất cả các 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 điệp Protobuf
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])

Nối các loại thông báo vào trường lặp lại

Nếu trường lặp lại không phải là loại scala, thì hành vi khi thêm các trường này vào 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 điệp 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 phải 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 điệp 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

Tin nhắn trống

Đôi khi, bạn cần biết liệu một thực thể thông báo có chứa thông tin nào hay không hoặc có đặt 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 điệp Protobuf
is_empty = campaign.ByteSize() == 0

Sao chép 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 thiết lập trường thông báo trống giống nhau bất kể loại thông báo bạn đang sử dụng. Bạn chỉ cần sao chép một thông báo trống vào trường cần thiết. Xem phần Sao chép thư cũng như hướng dẫn về Trường thư trống. Dưới đây là ví dụ về cách đặt trường thông báo trống:

client.copy_from(campaign.manual_cpm, client.get_type("ManualCpm"))

Tên trường là 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 ở cuối nếu tên đó cũng là một từ dành riêng trong Python. Sau đâ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 đủ tên được đặt trước được tạo trong mô-đun trình tạo gapic. Bạn cũng có thể truy cập vào thông tin này bằng cách lập trình.

Trước tiên, hãy cài đặt mô-đun:

python -m pip install gapic-generator

Sau đó, trong một tập lệnh hoặc REPL Python:

import gapic.utils
print(gapic.utils.reserved_names.RESERVED_NAMES)

Sự hiện diện trên trường

Vì các trường trên các thực thể thông báo protobuf có giá trị mặc định, nên không phải lúc nào bạn cũng biết được 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 điệp 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 protobuf Message có một phương thức HasField xác định xem trường trên một thông báo đã được đặt hay chưa, ngay cả khi trường đó được đặt thành giá trị mặc định.

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 thuận tiện 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 proto-plus 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ó câu hỏi về những thay đổi này hoặc gặp vấn đề khi di chuyển sang phiên bản mới nhất của thư viện, hãy gửi vấn đề trên công cụ theo dõi của chúng tôi.