Parametr konfiguracji use_proto_plus
pozwala określić, czy biblioteka ma zwracać wiadomości proto-plus czy wiadomości protobuf. Szczegółowe informacje o tym, jak ustawić ten parametr, znajdziesz w dokumentacji konfiguracji.
Z tej sekcji dowiesz się, jak wybór typu wiadomości wpływa na skuteczność. Dlatego zalecamy zapoznanie się z dostępnymi opcjami, aby podjąć świadomą decyzję.
Porównanie wiadomości proto-plus i protobuf
System przetwarzania kodu integruje proto-plus, aby poprawić ergonomię interfejsu wiadomości protobuf, sprawiając, że wiadomości zachowują się bardziej jak natywne obiekty Pythona. Oznacza to jednak, że korzystanie z proto-plus powoduje wzrost obciążenia wydajności.
Skuteczność proto-plus
Jedną z głównych zalet proto-plus jest to, że konwertuje wiadomości proto-plus i znane typy na natywne typy Pythona za pomocą procesu zwanego typem marshaling.
Marshalowanie występuje, gdy uzyskuje się dostęp do pola w przypadku wystąpienia wiadomości proto-plus, a w szczególności gdy pole jest odczytywane lub ustawiane, na przykład w definicji protobuf:
syntax = "proto3";
message Dog {
string name = 1;
}
Gdy ta definicja zostanie przekształcona w klasę proto-plus, będzie wyglądać mniej więcej tak:
import proto
class Dog(proto.Message):
name = proto.Field(proto.STRING, number=1)
Następnie możesz zainicjować klasę Dog
i uzyskać dostęp do jej pola name
tak jak do dowolnego innego obiektu Pythona:
dog = Dog()
dog.name = "Scruffy"
print(dog.name)
Podczas odczytu i ustawienia pola name
wartość jest konwertowana z rodzinnego typu Pythona str
na typ string
, aby była zgodna z czasem wykonywania protobuf.
Na podstawie analizy wydajności stwierdziliśmy, że czas potrzebny na przeprowadzenie tego typu konwersji ma na tyle duży wpływ na wydajność, że użytkownicy powinni sami decydować, czy chcą używać wiadomości protobuf.
Przypadki użycia wiadomości proto-plus i protobuf
- Przypadki użycia wiadomości proto-plus
- Proto-plus oferuje szereg ulepszeń ergonomicznych w porównaniu z wiadomościami protobuf, dzięki czemu są one idealne do pisania łatwego w utrzymaniu i czytelnego kodu. Ponieważ udostępniają one natywne obiekty Pythona, są łatwiejsze w użyciu i zrozumieniu.
- Zastosowania wiadomości Protobuf
- Używaj protokołów protobuf w przypadkach, w których liczy się wydajność, zwłaszcza w aplikacjach, które muszą szybko przetwarzać duże raporty lub które tworzą zapytania o zmianę z dużą liczbą operacji, np.
BatchJobService
lubOfflineUserDataJobService
.
Dynamiczna zmiana typów wiadomości
Po wybraniu odpowiedniego typu wiadomości dla aplikacji może się okazać, że w przypadku określonego procesu roboczego musisz użyć innego typu. W tym przypadku można łatwo przełączać się między tymi dwoma typami dynamicznie, korzystając z narzędzi oferowanych przez bibliotekę klienta. Przy użyciu tej samej klasy wiadomości Dog
z powyższego przykładu:
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)
Różnice w interfejsie wiadomości Protobuf
Interfejs proto-plus jest szczegółowo opisany, ale tutaj wyróżniliśmy kilka kluczowych różnic, które mają wpływ na typowe przypadki użycia biblioteki klienta Google Ads.
Serializacja bajtów
- Komunikaty proto-plus
serialized = type(campaign).serialize(campaign) deserialized = type(campaign).deserialize(serialized)
- komunikaty Protobuf;
serialized = campaign.SerializeToString() deserialized = campaign.FromString(serialized)
Serializacja w formacie JSON
- Komunikaty proto-plus
serialized = type(campaign).to_json(campaign) deserialized = type(campaign).from_json(serialized)
- komunikaty Protobuf;
from google.protobuf.json_format import MessageToJson, Parse serialized = MessageToJson(campaign) deserialized = Parse(serialized, campaign)
Maski pól
Metoda pomocnicza maski pola udostępniana przez api-core jest przeznaczona do używania instancji wiadomości protobuf. Dlatego, gdy używasz proto-plus, przekształcaj je w wiadomości protobuf, aby korzystać z pomocy:
- Komunikaty 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)
- komunikaty protokołu protobuf;
from google.api_core.protobuf_helpers import field_mask campaign = client.get_type("Campaign") mask = field_mask(None, campaign)
Wartości w polu enum
Enumy udostępniane przez wiadomości proto-plus są instancjami natywnego typu Pythona enum
, a zatem dziedziczą wiele metod ułatwiających pracę.
Pobieranie typu wyliczeniowego
Gdy używasz metody GoogleAdsClient.get_type
do pobierania typów wyliczeń, zwracane komunikaty różnią się nieco w zależności od tego, czy używasz komunikatów proto-plus czy protobuf. Na przykład:
- Komunikaty proto-plus
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
- komunikaty protokołu protobuf;
val = client.get_type("CampaignStatusEnum").PAUSED
Aby ułatwić pobieranie typów, w przypadku instancji GoogleAdsClient
jest dostępny atrybuty ułatwiający, który ma spójny interfejs niezależnie od tego, którego typu wiadomości używasz:
val = client.enums.CampaignStatusEnum.PAUSED
Pobieranie wartości typu wyliczeniowego
Czasami przydatna jest wartość lub identyfikator pola danego wyliczenia. Na przykład PAUSED
w polu CampaignStatusEnum
odpowiada 3
:
- Komunikaty proto-plus
campaign = client.get_type("Campaign") campaign.status = client.enums.CampaignStatusEnum.PAUSED # To read the value of campaign status print(campaign.status.value)
- komunikaty 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))
Pobieranie nazwy typu wyliczeniowego
Czasami warto znać nazwę pola typu enum. Na przykład podczas odczytywania obiektów z interfejsu API możesz chcieć wiedzieć, któremu stanowi kampanii odpowiada wartość int 3
:
- Komunikaty proto-plus
campaign = client.get_type("Campaign") campaign.status = client.enums.CampaignStatusEnum.PAUSED # To read the name of campaign status print(campaign.status.name)
- komunikaty 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)
Pola powtarzane
Jak opisano w dokumentacji proto-plus, pola powtarzające się są zazwyczaj równoważne z listami wpisów, co oznacza, że zachowują się prawie tak samo jak list
.
Dołączanie wartości do powtarzających się pól skalarnych
Podczas dodawania wartości do powtarzanych pól skalowania, np. pól string
lub int64
, interfejs jest taki sam niezależnie od typu wiadomości:
- Komunikaty proto-plus
ad.final_urls.append("https://www.example.com")
- komunikaty Protobuf;
ad.final_urls.append("https://www.example.com")
Obejmuje to wszystkie inne typowe metody list
, np. extend
:
- Komunikaty proto-plus
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
- komunikaty Protobuf;
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
Dołączanie typów wiadomości do pól powtarzalnych
Jeśli powtarzane pole nie jest polem typu skalarnego, jego dodawanie do powtarzanych pól działa nieco inaczej:
- Komunikaty proto-plus
frequency_cap = client.get_type("FrequencyCapEntry") frequency_cap.cap = 100 campaign.frequency_caps.append(frequency_cap)
- komunikaty Protobuf;
# The add method initializes a message and adds it to the repeated field frequency_cap = campaign.frequency_caps.add() frequency_cap.cap = 100
Przypisywanie pól powtarzalnych
W przypadku zarówno skalarnych, jak i nieskalarnych pól powtarzalnych możesz przypisywać do nich listy na różne sposoby:
- Komunikaty proto-plus
# In proto-plus it's possible to use assignment. urls = ["https://www.example.com"] ad.final_urls = urls
- komunikaty protokołu 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
puste wiadomości;
Czasami przydaje się wiedzieć, czy instancja wiadomości zawiera jakieś informacje lub czy ma ustawione jakieś pola.
- Komunikaty proto-plus
# When using proto-plus messages you can simply check the message for # truthiness. is_empty = bool(campaign) is_empty = not campaign
- komunikaty protokołu protobuf;
is_empty = campaign.ByteSize() == 0
Treść wiadomości
W przypadku wiadomości proto-plus i protobuf zalecamy użycie metody pomocniczej copy_from
w GoogleAdsClient
:
client.copy_from(campaign, other_campaign)
Puste pola wiadomości
Proces ustawiania pustych pól wiadomości jest taki sam niezależnie od używanego typu wiadomości. Wystarczy, że skopiujesz pustą wiadomość do odpowiedniego pola. Zapoznaj się z sekcją Kopia wiadomości oraz z poradnikiem dotyczącym pustych pól wiadomości. Oto przykład ustawienia pustego pola wiadomości:
client.copy_from(campaign.manual_cpm, client.get_type("ManualCpm"))
nazwy pól, które są zastrzeżonymi słowami;
Jeśli używasz wiadomości proto-plus, nazwy pól są automatycznie wyświetlane z podkreśleniem na końcu, jeśli nazwa jest też słowem zarezerwowanym w Pythonie. Oto przykład pracy z instancją Asset
:
asset = client.get_type("Asset")
asset.type_ = client.enums.AssetTypeEnum.IMAGE
Pełna lista nazw zastrzeżonych jest tworzona w module gapicgenerator. Dostęp do niego można uzyskać automatycznie.
Najpierw zainstaluj moduł:
python -m pip install gapic-generator
Następnie w replu lub skrypcie Pythona:
import gapic.utils
print(gapic.utils.reserved_names.RESERVED_NAMES)
Obecność w polu
Pola w instancjach wiadomości protobuf mają wartości domyślne, więc nie zawsze łatwo jest stwierdzić, czy dane pole zostało ustawione.
- Komunikaty proto-plus
# Use the "in" operator. has_field = "name" in campaign
- komunikaty protokołu protobuf;
campaign = client.get_type("Campaign") # Determines whether "name" is set and not just an empty string. campaign.HasField("name")
Interfejs klasy protobufMessage
ma metodę HasField
, która określa, czy pole w wiadomości zostało ustawione, nawet jeśli ma wartość domyślną.
Metody wiadomości Protobuf
Interfejs wiadomości protobuf zawiera kilka metod ułatwiających, które nie są częścią interfejsu proto-plus. Można jednak uzyskać do nich dostęp, konwertując wiadomość proto-plus na jej odpowiednik w formacie 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())
Śledzenie problemów
Jeśli masz pytania dotyczące tych zmian lub problemy z przeniesieniem do najnowszej wersji biblioteki, zgłoś problem w naszym systemie śledzenia błędów.