Protobuf mesajları

use_proto_plus yapılandırma parametresiyle, kitaplığın proto-plus mesajları mı yoksa protobuf mesajları mı döndürmesini istediğinizi belirtebilirsiniz. Bu parametrenin nasıl ayarlanacağıyla ilgili ayrıntılar için yapılandırma belgelerine bakın.

Bu bölümde, uygulamanız için en iyi yaklaşımı seçebilmeniz amacıyla her seçeneğin performans üzerindeki etkileri açıklanmaktadır.

Proto-plus ve protobuf mesajları

Kod oluşturucu ardışık düzeni, protobuf mesaj arayüzünün ergonomisini iyileştirmek için proto-plus'ı entegre eder. Bu sayede, protobuf mesaj arayüzü standart Python nesnelerine daha çok benzer. Ancak bu, proto-plus kullanmanın performans ek yükü getirdiği anlamına gelir.

Proto-plus performansı

Proto-plus'ın temel avantajlarından biri, tür sıralama adı verilen bir işlem aracılığıyla protobuf mesajlarını ve iyi bilinen türleri yerleşik Python türlerine dönüştürmesidir.

Sıralama, bir proto-plus mesaj örneğindeki bir alana erişildiğinde, özellikle de bir alan okunduğunda veya ayarlandığında gerçekleşir. Örneğin, bir protobuf tanımında:

syntax = "proto3";

message Dog {
  string name = 1;
}

Bu tanım bir proto-plus sınıfına dönüştürüldüğünde şu şekilde görünür:

import proto


class Dog(proto.Message):
    name = proto.Field(proto.STRING, number=1)

Ardından, Dog sınıfını ilk kullanıma hazırlayabilir ve diğer Python nesnelerinde olduğu gibi name alanına erişebilirsiniz:

dog = Dog()
dog.name = "Scruffy"
print(dog.name)

name alanı okunurken ve ayarlanırken değer, yerleşik bir Python str türünden string türüne dönüştürülür. Böylece değer, protobuf çalışma zamanıyla uyumlu olur.

Bu tür dönüşümleri gerçekleştirirken harcanan zamanın performans üzerindeki etkisi, uygulamanızın ihtiyaçlarına göre proto-plus veya protobuf mesajlarını kullanıp kullanmayacağınıza karar vermenizi gerektirecek kadar büyüktür.

Proto-plus ve protobuf mesajlarının kullanım alanları

Proto-plus mesaj kullanım alanları
Proto-plus, protobuf mesajlarına kıyasla ergonomik açıdan çeşitli iyileştirmeler sunar. Bu nedenle, sürdürülebilir ve okunabilir kod yazmak için idealdir. Standart Python nesnelerini gösterdikleri için kullanımı ve anlaşılması daha kolaydır.
Protobuf mesajı kullanım alanları
Performansa duyarlı kullanım alanları için protobuf'ları kullanın. Özellikle büyük raporları hızlı bir şekilde işlemesi gereken veya çok sayıda işlem içeren değişiklik istekleri oluşturan uygulamalarda (ör. BatchJobService veya OfflineUserDataJobService ile) protobuf'ları kullanın.

Mesaj türleri arasında dinamik olarak geçiş yapma

Uygulamanız için uygun mesaj türünü seçtikten sonra belirli bir iş akışı için diğer türü kullanmanız gerektiğini fark edebilirsiniz. Bu durumda, istemci kitaplığının sunduğu yardımcı programları kullanarak iki tür arasında dinamik olarak geçiş yapabilirsiniz. Daha önce kullandığınız Dog mesaj sınıfını kullanarak:

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 mesaj arayüzü farklılıkları

Proto-plus arayüzü ayrıntılı olarak belgelenmiştir. Aşağıdaki bölümlerde, Google Ads istemci kitaplığının yaygın kullanım alanlarını etkileyen temel farklılıklar vurgulanmaktadır.

Bayt serileştirme

Proto-plus mesajları
serialized = type(campaign).serialize(campaign)
deserialized = type(campaign).deserialize(serialized)
Protobuf mesajları
serialized = campaign.SerializeToString()
deserialized = campaign.FromString(serialized)

JSON serileştirme

Proto-plus mesajları
serialized = type(campaign).to_json(campaign)
deserialized = type(campaign).from_json(serialized)
Protobuf mesajları
from google.protobuf.json_format import MessageToJson, Parse

serialized = MessageToJson(campaign)
deserialized = Parse(serialized, campaign)

Alan maskeleri

api-core tarafından sağlanan alan maskesi yardımcı yöntemi, protobuf mesaj örneklerini kullanmak için tasarlanmıştır. Proto-plus mesajları kullanırken yardımcıyı kullanmak için bunları protobuf mesajlarına dönüştürün:

Proto-plus mesajları
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 mesajları
from google.api_core.protobuf_helpers import field_mask

campaign = client.get_type("Campaign")
mask = field_mask(None, campaign)

Sıralamalar

Proto-plus mesajları tarafından gösterilen enum'lar, Python'un yerleşik enum türünün örnekleridir ve bu nedenle bir dizi kolaylık sağlayan yöntem devralır.

Enum türü alma

Numaralandırmaları almak için GoogleAdsClient.get_type yöntemini kullanırken döndürülen mesajlar, proto-plus veya protobuf mesajları kullanmanıza bağlı olarak biraz farklılık gösterir. Örneğin:

Proto-plus mesajları
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
Protobuf mesajları
val = client.get_type("CampaignStatusEnum").PAUSED

Numaralandırmaları almayı kolaylaştırmak için GoogleAdsClient örneklerinde, kullandığınız mesaj türünden bağımsız olarak tutarlı bir arayüze sahip olan bir kolaylık özelliği vardır:

val = client.enums.CampaignStatusEnum.PAUSED

Enum değeri alma

Bazen belirli bir enum'un değerini veya alan kimliğini bilmek yararlı olabilir. Örneğin, CampaignStatusEnum üzerindeki PAUSED, 3 değerine karşılık gelir:

Proto-plus mesajları
campaign = client.get_type("Campaign")
campaign.status = client.enums.CampaignStatusEnum.PAUSED
# To read the value of campaign status
print(campaign.status.value)
Protobuf mesajları
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 adı alma

Bazen bir enum alanının adını bilmek faydalı olabilir. Örneğin, API'den nesneleri okurken 3 tam sayısının hangi kampanya durumuna karşılık geldiğini bilmek isteyebilirsiniz:

Proto-plus mesajları
campaign = client.get_type("Campaign")
campaign.status = client.enums.CampaignStatusEnum.PAUSED
# To read the name of campaign status
print(campaign.status.name)
Protobuf mesajları
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))

Yinelenen alanlar

Proto-plus belgelerinde açıklandığı gibi, yinelenen alanlar genellikle yazılı listelere eşdeğerdir. Bu, list ile neredeyse aynı şekilde davrandıkları anlamına gelir.

Yinelenen skaler alanlara değer ekleme

Yinelenen skaler tür alanlarına (ör. string veya int64 alanları) değer eklerken arayüz, mesaj türünden bağımsız olarak aynıdır:

Proto-plus mesajları
ad.final_urls.append("https://www.example.com")
Protobuf mesajları
ad.final_urls.append("https://www.example.com")

Bu, diğer tüm yaygın list yöntemlerini de içerir (ör. extend):

Proto-plus mesajları
ad.final_urls.extend(
    ["https://www.example.com", "https://www.example.com/2"]
)
Protobuf mesajları
ad.final_urls.extend(
    ["https://www.example.com", "https://www.example.com/2"]
)

Mesaj türlerini yinelenen alanlara ekleme

Yinelenen alan skaler tür değilse yinelenen alanlara ekleme davranışı biraz farklıdır:

Proto-plus mesajları
frequency_cap = client.get_type("FrequencyCapEntry")
frequency_cap.cap = 100
campaign.frequency_caps.append(frequency_cap)
Protobuf mesajları
# The add method initializes a message and adds it to the repeated field
frequency_cap = campaign.frequency_caps.add()
frequency_cap.cap = 100

Yinelenen alanları atama

Hem skaler hem de skaler olmayan yinelenen alanlar için alana farklı şekillerde liste atayabilirsiniz:

Proto-plus mesajları
# In proto-plus it's possible to use assignment.
urls = ["https://www.example.com"]
ad.final_urls = urls
Protobuf mesajları
# 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

Boş mesajlar

Bazen bir mesaj örneğinin herhangi bir bilgi içerip içermediğini veya alanlarından herhangi birinin ayarlanıp ayarlanmadığını bilmek yararlı olabilir.

Proto-plus mesajları
# When using proto-plus messages you can check the message for truthiness.
is_empty = not bool(campaign)
Protobuf mesajları
is_empty = campaign.ByteSize() == 0

Mesaj kopyası

Hem proto-plus hem de protobuf mesajları için GoogleAdsClient üzerinde copy_from yardımcı yöntemini kullanın:

client.copy_from(campaign, other_campaign)

Boş mesaj alanları

Boş mesaj alanlarını ayarlama işlemi, kullandığınız mesaj türünden bağımsız olarak aynıdır. Söz konusu alana boş bir mesaj kopyalarsanız. Mesaj kopyası bölümüne ve Boş mesaj alanları kılavuzuna bakın. Aşağıdaki örnekte, boş bir mesaj alanının nasıl ayarlanacağı gösterilmektedir:

client.copy_from(campaign.manual_cpm, client.get_type("ManualCpm"))

Ayrılmış kelimeler olan alan adları

Proto-plus mesajları kullanırken, alan adları Python'da ayrılmış bir kelimeyse otomatik olarak sonunda alt çizgiyle görünür. Aşağıdaki örnekte, Asset örneğiyle nasıl çalışılacağı gösterilmektedir:

asset = client.get_type("Asset")
asset.type_ = client.enums.AssetTypeEnum.IMAGE

Ayrılmış adların tam listesi, gapic generator modülünde oluşturulur. Bu verilere programatik olarak da erişilebilir.

Öncelikle modülü yükleyin:

python -m pip install gapic-generator

Ardından, bir Python REPL veya komut dosyasında:

import gapic.utils

print(gapic.utils.reserved_names.RESERVED_NAMES)

Saha varlığı

Protobuf mesaj örneklerindeki alanların varsayılan değerleri olduğundan, bir alanın ayarlanıp ayarlanmadığını anlamak her zaman kolay değildir.

Proto-plus mesajları
# Use the "in" operator.
has_field = "name" in campaign
Protobuf mesajları
campaign = client.get_type("Campaign")
# Determines whether "name" is set and not just an empty string.
campaign.HasField("name")

Protobuf Message sınıf arayüzünde, bir mesajdaki alt mesajın, oneof alanının veya optional skaler alanının ayarlanıp ayarlanmadığını (varsayılan değere ayarlanmış olsa bile) belirleyen bir HasField yöntemi vardır. (proto3 içindeki isteğe bağlı olmayan skaler alanlarda HasField çağrısı yapıldığında ValueError hatası oluşur.)

Protobuf mesaj yöntemleri

Protobuf mesaj arayüzü, proto-plus arayüzünün parçası olmayan bazı kullanışlı yöntemler içerir. Ancak proto-plus mesajını protobuf karşılığına dönüştürerek bunlara erişebilirsiniz:

# 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

Bu değişikliklerle ilgili sorularınız varsa veya kitaplığın en yeni sürümüne geçiş yaparken sorun yaşarsanız Issue Tracker'da sorun bildirin.