با پارامتر پیکربندی use_proto_plus، میتوانید مشخص کنید که میخواهید کتابخانه پیامهای proto-plus یا پیامهای protobuf را برگرداند. برای جزئیات مربوط به نحوه
تنظیم این پارامتر، اسناد پیکربندی را ببینید.
این بخش پیامدهای عملکردی هر گزینه را شرح میدهد تا بتوانید بهترین رویکرد را برای برنامهتان انتخاب کنید.
پیامهای Proto-plus درمقابل protobuf
خط لوله تولیدکننده کد proto-plus را ادغام میکند تا ارگونومی میانای پیام protobuf را با شبیهتر کردن رفتار آنها به اشیای استاندارد Python بهبود بخشد. بااینحال، این یعنی استفاده از proto-plus سربار عملکرد ایجاد میکند.
عملکرد Proto-plus
یکی از مزایای اصلی proto-plus این است که پیامهای protobuf و انواع شناختهشده را ازطریق فرایندی بهنام مرتبسازی نوع به انواع Python داخلی تبدیل میکند.
مرتبسازی زمانی اتفاق میافتد که به فیلدی در نمونه پیام 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 سازگار باشد.
زمان صرفشده برای انجام این تبدیلهای نوع تأثیر عملکردی بهاندازه کافی بزرگی دارد که باید براساس نیازهای برنامهتان تصمیم بگیرید که از پیامهای proto-plus یا protobuf استفاده کنید یا نه.
موارد استفاده برای پیامهای proto-plus و protobuf
- موارد استفاده از پیام Proto-plus
- Proto-plus تعدادی بهبود ارگونومیک نسبتبه پیامهای protobuf ارائه میدهد، بنابراین برای نوشتن کد قابلنگهداری و خوانا ایدهآل هستند. ازآنجاییکه این مدلها اشیاء استاندارد Python را نمایش میدهند، استفاده و درک آنها آسانتر است.
- موارد استفاده پیام Protobuf
- از protobufs برای موارد استفاده حساس به عملکرد استفاده کنید، بهویژه در برنامههایی که
باید گزارشهای بزرگ را بهسرعت پردازش کنند، یا درخواستهای تغییر را با
تعداد زیادی عملیات بسازند، برای مثال با
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 با جزئیات مستند شده است، و بخشهای زیر تفاوتهای کلیدی را که بر موارد استفاده رایج برای کتابخانه مشتری Google Ads تأثیر میگذارند برجسته میکنند.
سریالسازی بایتها
- پیامهای Proto-plus
serialized = type(campaign).serialize(campaign) deserialized = type(campaign).deserialize(serialized)
- پیامهای Protobuf
serialized = campaign.SerializeToString() deserialized = campaign.FromString(serialized)
سریالسازی JSON
- پیامهای Proto-plus
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-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)
- پیامهای Protobuf
from google.api_core.protobuf_helpers import field_mask campaign = client.get_type("Campaign") mask = field_mask(None, campaign)
شمارشیها
Enums exposed by proto-plus messages are instances of Python's built-in
enum type and therefore inherit a number of convenience
methods.
بازیابی نوع شمارشی
هنگام استفاده از روش GoogleAdsClient.get_type برای بازیابی شمارشیها، پیامهایی که برگردانده میشوند بسته به اینکه از پیامهای proto-plus یا protobuf استفاده میکنید کمی متفاوت هستند. برای مثال:
- پیامهای Proto-plus
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
- پیامهای Protobuf
val = client.get_type("CampaignStatusEnum").PAUSED
برای سادهتر کردن بازیابی شمارشها، یک مشخصه راحتی در نمونههای GoogleAdsClient وجود دارد که صرفنظر از نوع پیامی که استفاده میکنید، میانای ثابتی دارد:
val = client.enums.CampaignStatusEnum.PAUSED
بازیابی مقدار Enum
گاهی اوقات دانستن مقدار یا شناسه فیلد یک enum خاص مفید است، برای مثال، PAUSED در CampaignStatusEnum با 3 مطابقت دارد:
- پیامهای Proto-plus
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 # Native protobuf enum fields already store the integer value (3): print(campaign.status) # Or look up the integer value from the enum name string: print(status_enum.CampaignStatus.Value("PAUSED"))
بازیابی نام شمارشی
گاهی اوقات دانستن نام فیلد enum مفید است. برای مثال، هنگام خواندن اشیا از میانای برنامهسازی کاربردی، ممکن است بخواهید بدانید عدد صحیح 3 با کدام وضعیت پویش مطابقت دارد:
- پیامهای Proto-plus
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 print(status_enum.CampaignStatus.Name(campaign.status))
فیلدهای تکراری
همانطور که در اسناد proto-plus شرح داده شده است، فیلدهای تکراری
عموماً معادل فهرستهای تایپشده هستند، یعنی تقریباً
رفتاری مشابه با list دارند.
افزودن مقادیر به فیلدهای اسکالر تکراری
هنگام افزودن مقادیر به فیلدهای تکراری
نوع اسکالر، برای مثال فیلدهای string
یا int64، رابط کاربری بدون توجه به نوع پیام یکسان است:
- پیامهای Proto-plus
ad.final_urls.append("https://www.example.com")
- پیامهای Protobuf
ad.final_urls.append("https://www.example.com")
این شامل همه روشهای رایج دیگر list نیز میشود، برای مثال extend:
- پیامهای Proto-plus
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"] )
افزودن انواع پیام به فیلدهای تکراری
اگر فیلد تکراری از نوع اسکالر نباشد، رفتار هنگام افزودن آنها به فیلدهای تکراری کمی متفاوت است:
- پیامهای Proto-plus
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-plus
# 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-plus
# When using proto-plus messages you can check the message for truthiness. is_empty = not bool(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
سپس، در یک REPL یا اسکریپت Python:
import gapic.utils
print(gapic.utils.reserved_names.RESERVED_NAMES)
حضور در محل
ازآنجاییکه فیلدهای نمونههای پیام protobuf دارای مقادیر پیشفرض هستند، همیشه نمیتوان بهراحتی تشخیص داد که آیا فیلدی تنظیم شده است یا نه.
- پیامهای Proto-plus
# 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 است که تعیین میکند آیا زیرپیام، فیلد oneof، یا فیلد اسکالر optional در پیام تنظیم شده است یا نه، حتی اگر روی مقدار پیشفرض تنظیم شده باشد.
(فراخوانی HasField در فیلدهای اسکالر غیراختیاری در proto3 باعث ایجاد
ValueError میشود.)
روشهای پیام Protobuf
میانای پیام protobuf شامل برخی روشهای راحتی است که بخشی از میانای proto-plus نیستند؛ بااینحال، میتوانید با تبدیل پیام proto-plus به همتای protobuf آن، به آنها دسترسی پیدا کنید:
# Accessing the ListFields method
protobuf_campaign = util.convert_proto_plus_to_protobuf(campaign)
print(protobuf_campaign.ListFields())
# Accessing the Clear method
protobuf_campaign = util.convert_proto_plus_to_protobuf(campaign)
protobuf_campaign.Clear()
پیگیریکننده نسخه
اگر درباره این تغییرات سؤالی دارید یا در انتقال به جدیدترین نسخه کتابخانه با مشکلی مواجه شدهاید، مشکل را در سیستم ردیابی مشکل ثبت کنید.