باستخدام مَعلمة الإعداد 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 وتعيينه، يتم تحويل القيمة من نوع str مضمّن في Python إلى نوع string لكي تكون القيمة متوافقة مع وقت تشغيل البروتوكول.
إنّ الوقت المستغرَق في تنفيذ عمليات تحويل الأنواع هذه له تأثير كبير على الأداء، لذا عليك تحديد ما إذا كنت ستستخدم رسائل proto-plus أو protobuf استنادًا إلى احتياجات تطبيقك.
حالات استخدام رسائل proto-plus وprotobuf
- حالات استخدام رسائل Proto-plus
- توفّر Proto-plus عددًا من التحسينات المريحة مقارنةً برسائل protobuf، لذا فهي مثالية لكتابة رمز برمجي قابل للصيانة وسهل القراءة. وبما أنّها تعرض عناصر 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 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 لاستخدام مثيلات رسائل البروتوكول المخزَّن مؤقتًا. عند استخدام رسائل 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 # 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"))
استرداد اسم التعداد
في بعض الأحيان، يكون من المفيد معرفة اسم حقل التعداد. على سبيل المثال، عند قراءة عناصر من واجهة برمجة التطبيقات، قد تريد معرفة حالة الحملة التي يتوافق معها العدد الصحيح 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. ويمكن الوصول إليها آليًا أيضًا.
أولاً، ثبِّت الوحدة:
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 تحدّد ما إذا تم ضبط رسالة فرعية أو حقل oneof أو حقل optional
عددي في رسالة، حتى إذا تم ضبطه على قيمة تلقائية.
(يؤدي استدعاء HasField على حقول عددية غير اختيارية في proto3 إلى حدوث ValueError.)
طُرق رسائل Protobuf
تتضمّن واجهة رسائل البروتوكول المخزَّن مؤقتًا بعض الطرق المريحة التي لا تشكّل جزءًا من واجهة proto-plus، ولكن يمكنك الوصول إليها من خلال تحويل رسالة proto-plus إلى رسالة البروتوكول المخزَّن مؤقتًا المقابلة لها:
# 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()
أداة تتبّع المشاكل
إذا كانت لديك أي أسئلة حول هذه التغييرات أو أي مشاكل في نقل البيانات إلى أحدث إصدار من المكتبة، يمكنك تسجيل مشكلة في أداة تتبُّع المشاكل.