باستخدام مَعلمة الضبط use_proto_plus
، يمكنك تحديد ما إذا كنت تريد أن تعرض المكتبة
رسائل proto-plus أو
رسائل protobuf. للحصول على تفاصيل حول كيفية ضبط هذه المَعلمة، اطّلِع على مستندات الإعداد.
يوضّح هذا القسم الآثار المترتبة على الأداء عند اختيار أنواع الرسائل التي سيتم استخدامها، لذا ننصحك بقراءة الخيارات وفهمها لاتخاذ قرار مدروس.
الفرق بين رسائل Proto-plus ورسائل Protobuf
تدمج سلسلة معالجة مولّد الرموز proto-plus كطريقة لتحسين سهولة استخدام واجهة رسائل البروتوكول من خلال جعلها تتصرف بشكل مشابه لكائنات 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
وتعيينه، يتم تحويل القيمة من نوع str
أصلي في Python إلى نوع string
لكي تكون القيمة متوافقة مع وقت تشغيل البروتوكول.
استنادًا إلى تحليلات الأداء التي أجريناها، تبيّن لنا أنّ الوقت المستغرَق في إجراء عمليات التحويل هذه يؤثّر بشكل كبير في الأداء، لذا يجب أن يقرّر المستخدمون، استنادًا إلى احتياجاتهم، ما إذا كانوا سيستخدمون رسائل protobuf أم لا.
حالات استخدام رسائل proto-plus وprotobuf
- حالات استخدام رسائل Proto-plus
- تقدّم 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 بالتفصيل، ولكن سنوضّح هنا بعض الاختلافات الرئيسية التي تؤثر في حالات الاستخدام الشائعة لمكتبة برامج "إعلانات Google" للعملاء.
تسلسل وحدات البايت
- رسائل 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)
عمليات التعداد
إنّ التعدادات التي تعرضها رسائل proto-plus هي مثيلات من نوع
enum
الأصلي في Python، وبالتالي
تتضمّن عددًا من طرق الاستخدام السهل.
استرداد نوع التعداد
عند استخدام طريقة 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
استرداد قيمة التعداد
في بعض الأحيان، يكون من المفيد معرفة قيمة أو رقم تعريف حقل تعداد معيّن، على سبيل المثال، 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 # To read the value of campaign status print(status_enum.CampaignStatus.Value(campaign.status))
استرداد اسم التعداد
في بعض الأحيان، يكون من المفيد معرفة اسم حقل تعداد. على سبيل المثال، عند قراءة عناصر من واجهة برمجة التطبيقات، قد تحتاج إلى معرفة حالة الحملة التي يتوافق معها العدد الصحيح 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 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 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. ويمكن الوصول إليه آليًا أيضًا.
أولاً، ثبِّت الوحدة:
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")
يحتوي صف
Message
protobuf على طريقة 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())
أداة تتبّع المشاكل
إذا كانت لديك أي أسئلة حول هذه التغييرات أو أي مشاكل في نقل البيانات إلى أحدث إصدار من المكتبة، يمكنك تسجيل مشكلة في أداة تتبُّع المشاكل.