Thông báo Protobuf

Phiên bản 14.0.0 của thư viện ứng dụng Python giới thiệu một thông số cấu hình bắt buộc mới có tên là use_proto_plus chỉ định xem bạn có muốn thư viện trả về hay không thông báo proto-plus hoặc 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ả ngụ ý của việc chọn loại thông báo để sử dụng, do đó, bạn nên đọc và hiểu rõ các lựa chọn để đưa ra quyết định sáng suốt. Tuy nhiên, nếu bạn muốn nâng cấp lên phiên bản 14.0.0 mà không cần thay đổi mã, bạn có thể đặt use_proto_plus thành True để tránh làm hỏng các thay đổi 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 trình tạo mã mới quy trình này đã tích hợp proto-plus như một cách cải thiện tính công thái học trên giao diện thông báo protobuf bằng cách làm cho chúng hoạt động tốt hơn như các đối tượng Python gốc. Sự đánh đổi của sự cải tiến này là cộng đồng proto đưa ra 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 protobuf tin nhắncác loại phổ biến đến các kiểu Python gốc thông qua một quy trình có tên là kiểu so khớp.

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ể khi một trường được đọc hoặc đặt, ví dụ như trong một protobuf định nghĩa:

syntax = "proto3";

message Dog {
  string name = 1;
}

Khi chuyển đổi định nghĩa này sang lớp proto-plus, nó sẽ trô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 này theo cách bạn muốn 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ừ một thuộc tính gốc Nhập str trong Python thành loại string để rằng giá trị này 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 loại chuyển đổi này đủ lớn ảnh hưởng đến hiệu suất mà điều quan trọng là phải cung cấp cho người dùng lựa chọn sử dụng protobuf tin nhắn.

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, chúng trở nên lý tưởng để viết mã có thể bảo trì và đọc được. Vì chúng tiết lộ đối tượng Python gốc 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 ứ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 bằng số lượng lớn thao tác, ví dụ: BatchJobService hoặc OfflineUserDataJobService.

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 sẽ thấy mà bạn cần sử dụng loại còn lại cho quy trình làm việc cụ thể. Trong trường hợp này, dễ dàng chuyển đổi giữa hai loại một cách linh động bằng cách sử dụng các tiện ích do thư viện ứng dụng. 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 trong 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 khách hàng Google Ads thư viện của bạn.

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 được cung cấp bởi api-core được thiết kế để sử dụng protobuf lần xuất hiện thông báo. Vì vậy, khi sử dụng thông báo proto-plus, hãy chuyển đổi chúng thành protobuf các thông báo để 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

Enum hiển thị bởi các thông điệp proto-plus là các phiên bản gốc của Python Loại enum 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, thông báo được trả về sẽ hơi khác nhau, tuỳ thuộc vào việc bạn sử dụng thông báo proto-plus hoặc 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

Để đơn giản hoá việc truy xuất giá trị enum, 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ể loại thông báo bạn đang sử dụng:

val = client.enums.CampaignStatusEnum.PAUSED

Truy xuất giá trị enum

Đôi khi, sẽ rất hữu ích khi biết giá trị hoặc mã trường của một enum nhất định, cho 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 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 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ư được mô tả trong cấu trúc proto-plus tài liệu, các trường lặp lại thường tương đương với danh sách đã nhập, tức là chúng hoạt động gần giống 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 đại lượng vô hướng lặp lại trường type, ví dụ: Trường string hoặc int64, giao diện như nhau bất kể thông báo loại:

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à đại lượng vô hướng loại, hành vi khi thêm chúng vào các trường lặp lại 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 những cách khác nhau:

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 phiên bản thông báo có chứa bất kỳ hoặc có bất kỳ trường nào được đặt 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 copy_from phương thức trợ giúp 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 là như nhau bất kể loại thông báo mà bạn đang sử dụng. Bạn chỉ cần sao chép một tin nhắn trống vào trường này liên quan. Xem mục Nội dung thư cũng như Thư trống Hướng dẫn về các trường. Sau đây là ví dụ về cách để đặ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 báo proto-plus, tên trường sẽ tự động xuất hiện cùng 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à một 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 chiến dịch đặt trước tên được xây dựng trong thời gian trình tạo. Có thể cũng truy cập được 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 trường luôn 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")

Protobuf Message giao diện lớp có phương thức HasField xác định xem trường trên đã được đặt, ngay cả khi thông báo đó đượ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 của giao diện proto-plus; tuy nhiên, bạn có thể dễ dàng truy cập chúng 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ó 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 di chuyển sang phiên bản 14.0.0 của thư viện, hãy gửi trên vòng đeo tay theo dõi.