باستخدام مَعلمة الضبط 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 لكي تكون القيمة متوافقة مع وقت تشغيل 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".
تسلسل وحدات البايت
- رسائل 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. When using proto-plus messages,
convert them to protobuf messages to use the helper:
- رسائل 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، وبالتالي تكتسب عددًا من الطرق المريحة.
استرداد نوع التعداد
When using the GoogleAdsClient.get_type method to retrieve enums, the messages
that are returned are slightly different depending on whether you're using
proto-plus or protobuf messages. على سبيل المثال:
- رسائل Proto-plus
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
- رسائل Protobuf
val = client.get_type("CampaignStatusEnum").PAUSED
لتسهيل استرداد التعدادات، تتوفّر سمة ملائمة في مثيلات GoogleAdsClient التي تتضمّن واجهة متّسقة بغض النظر عن نوع الرسالة التي تستخدمها:
val = client.enums.CampaignStatusEnum.PAUSED
استرداد قيمة التعداد
Sometimes it's useful to know the value, or field ID, of a given enum, for
example, PAUSED on CampaignStatusEnum corresponds to 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 generator. ويمكن الوصول إليها برمجيًا أيضًا.
أولاً، ثبِّت الوحدة:
python -m pip install gapic-generator
بعد ذلك، في Python REPL أو نص برمجي:
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()
Issue Tracker
إذا كانت لديك أي أسئلة حول هذه التغييرات أو أي مشاكل في نقل البيانات إلى أحدث إصدار من المكتبة، يمكنك تقديم مشكلة في Issue Tracker.