Za pomocą parametru konfiguracji use_proto_plus
możesz 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.
W tej sekcji opisujemy wpływ wyboru typów wiadomości na skuteczność, dlatego zalecamy zapoznanie się z opcjami, aby podjąć świadomą decyzję.
Wiadomości proto-plus a wiadomości protobuf
Potok generatora kodu integruje bibliotekę proto-plus, aby ulepszyć interfejs komunikatów protobuf, sprawiając, że zachowują się one bardziej jak natywne obiekty Pythona. Oznacza to jednak, że używanie proto-plus wiąże się z obniżeniem wydajności.
Skuteczność Proto-plus
Jedną z głównych zalet proto-plus jest to, że przekształca komunikaty protobuf i znane typy na natywne typy Pythona w procesie zwanym marshalizacją typów.
Marshaling występuje, gdy uzyskuje się dostęp do pola w instancji wiadomości proto-plus, a konkretnie wtedy, gdy pole jest odczytywane lub ustawiane, na przykład w definicji protobuf:
syntax = "proto3";
message Dog {
string name = 1;
}
Po przekształceniu tej definicji w klasę proto-plus będzie ona 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 w przypadku każdego innego obiektu Pythona:
dog = Dog()
dog.name = "Scruffy"
print(dog.name)
Podczas odczytywania i ustawiania pola name
wartość jest konwertowana z natywnego typu Pythona str
na typ string
, aby była zgodna z czasem działania protokołu buforów protokołu.
Na podstawie naszych analiz wydajności stwierdziliśmy, że czas poświęcony na konwersje tego typu ma wystarczająco duży wpływ na wydajność, aby użytkownicy mogli zdecydować, czy chcą używać wiadomości protobuf, w zależności od swoich potrzeb.
Przypadki użycia wiadomości proto-plus i protobuf
- Przykłady użycia wiadomości Proto-plus
- Proto-plus oferuje szereg ulepszeń ergonomicznych w porównaniu z wiadomościami protobuf, dzięki czemu idealnie nadaje się do pisania kodu, który jest łatwy w utrzymaniu i czytelny. Ponieważ udostępniają one natywne obiekty Pythona, są łatwiejsze w użyciu i zrozumieniu.
- Przykłady użycia wiadomości Protobuf
- Używaj protobufów w przypadkach, w których wydajność jest kluczowa, zwłaszcza w aplikacjach, które muszą szybko przetwarzać duże raporty lub tworzyć żądania zmiany z dużą liczbą operacji, np. z
BatchJobService
lubOfflineUserDataJobService
.
Dynamiczna zmiana typów wiadomości
Po wybraniu odpowiedniego typu wiadomości dla aplikacji może się okazać, że w określonym przepływie pracy musisz użyć innego typu. W tym przypadku łatwo jest dynamicznie przełączać się między tymi 2 rodzajami za pomocą narzędzi oferowanych przez bibliotekę klienta. Korzystając z tej samej Dog
klasy wiadomości co powyżej:
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 zwrócimy uwagę na niektóre kluczowe różnice, które mają wpływ na typowe przypadki użycia biblioteki klienta Google Ads.
Serializacja bajtów
- Wiadomości Proto-plus
serialized = type(campaign).serialize(campaign) deserialized = type(campaign).deserialize(serialized)
- Wiadomości Protobuf
serialized = campaign.SerializeToString() deserialized = campaign.FromString(serialized)
Serializacja JSON
- Wiadomości Proto-plus
serialized = type(campaign).to_json(campaign) deserialized = type(campaign).from_json(serialized)
- Wiadomości 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 bibliotekę api-core jest przeznaczona do używania instancji wiadomości protobuf. Dlatego podczas korzystania z wiadomości proto-plus przekonwertuj je na wiadomości protobuf, aby użyć funkcji pomocniczej:
- Wiadomości 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)
- Wiadomości 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
Wyliczenia udostępniane przez wiadomości proto-plus są instancjami natywnego typu Pythona
enum
, dlatego dziedziczą szereg wygodnych metod.
Pobieranie typu wyliczeniowego
Gdy do pobierania wyliczeń używasz metody GoogleAdsClient.get_type
, zwracane komunikaty różnią się nieznacznie w zależności od tego, czy używasz komunikatów proto-plus czy protobuf. Na przykład:
- Wiadomości Proto-plus
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
- Wiadomości Protobuf
val = client.get_type("CampaignStatusEnum").PAUSED
Aby ułatwić pobieranie wyliczeń, w przypadku instancji GoogleAdsClient
dostępny jest atrybut wygody, który ma spójny interfejs niezależnie od używanego typu wiadomości:
val = client.enums.CampaignStatusEnum.PAUSED
Pobieranie wartości typu wyliczeniowego
Czasami warto znać wartość lub identyfikator pola danego wyliczenia, np. PAUSED
w CampaignStatusEnum
odpowiada 3
:
- Wiadomości proto-plus
campaign = client.get_type("Campaign") campaign.status = client.enums.CampaignStatusEnum.PAUSED # To read the value of campaign status print(campaign.status.value)
- Wiadomości 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 wyliczeniowego. Na przykład podczas odczytywania obiektów z interfejsu API możesz chcieć wiedzieć, jaki stan kampanii odpowiada liczbie całkowitej 3
:
- Wiadomości proto-plus
campaign = client.get_type("Campaign") campaign.status = client.enums.CampaignStatusEnum.PAUSED # To read the name of campaign status print(campaign.status.name)
- Wiadomości 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 powtarzane są zwykle odpowiednikami list typowanych, co oznacza, że zachowują się niemal identycznie jak list
.
Dołączanie wartości do powtarzanych pól skalarnych
Podczas dodawania wartości do powtórzonych pól typu skalarnego, np. pól string
lub int64
, interfejs jest taki sam niezależnie od typu wiadomości:
- Wiadomości Proto-plus
ad.final_urls.append("https://www.example.com")
- Wiadomości Protobuf
ad.final_urls.append("https://www.example.com")
Obejmuje to również wszystkie inne popularne metody list
, np. extend
:
- Wiadomości proto-plus
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
- Wiadomości Protobuf
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
Dołączanie typów wiadomości do powtórzonych pól
Jeśli pole powtarzane nie jest typu skalarnego, zachowanie podczas dodawania go do pól powtarzanych jest nieco inne:
- Wiadomości proto-plus
frequency_cap = client.get_type("FrequencyCapEntry") frequency_cap.cap = 100 campaign.frequency_caps.append(frequency_cap)
- Wiadomości 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 powtarzanych
W przypadku skalarnych i nieskalarnych pól powtarzanych możesz przypisywać listy do pola na różne sposoby:
- Wiadomości Proto-plus
# In proto-plus it's possible to use assignment. urls = ["https://www.example.com"] ad.final_urls = urls
- Wiadomości 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 warto wiedzieć, czy instancja wiadomości zawiera jakiekolwiek informacje lub czy którekolwiek z jej pól jest ustawione.
- Wiadomości Proto-plus
# When using proto-plus messages you can simply check the message for # truthiness. is_empty = bool(campaign) is_empty = not campaign
- Wiadomości Protobuf
is_empty = campaign.ByteSize() == 0
Treść wiadomości
Zarówno w przypadku wiadomości proto-plus, jak i protobuf zalecamy używanie metody pomocniczej copy_from
w obiekcie GoogleAdsClient
:
client.copy_from(campaign, other_campaign)
Puste pola wiadomości
Proces ustawiania pustych pól wiadomości jest taki sam niezależnie od typu wiadomości, którego używasz. Wystarczy skopiować pustą wiadomość do odpowiedniego pola. Zapoznaj się z sekcją Kopia wiadomości oraz z przewodnikiem Puste pola 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ą słowami zastrzeżonymi
W przypadku korzystania z wiadomości proto-plus nazwy pól automatycznie pojawiają się z podkreśleniem na końcu, jeśli nazwa jest również słowem zastrzeżonym 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 generatora gapic. Możesz też uzyskać do niego dostęp automatycznie.
Najpierw zainstaluj moduł:
python -m pip install gapic-generator
Następnie w interpreterze Python REPL lub skrypcie:
import gapic.utils
print(gapic.utils.reserved_names.RESERVED_NAMES)
Obecność pola
Pola w instancjach wiadomości protobuf mają wartości domyślne, więc nie zawsze wiadomo, czy pole zostało ustawione.
- Wiadomości Proto-plus
# Use the "in" operator. has_field = "name" in campaign
- Wiadomości Protobuf
campaign = client.get_type("Campaign") # Determines whether "name" is set and not just an empty string. campaign.HasField("name")
Interfejs klasy protobuf Message
zawiera metodę HasField
, która określa, czy pole w wiadomości zostało ustawione, nawet jeśli ustawiono wartość domyślną.
Metody wiadomości Protobuf
Interfejs wiadomości protobuf zawiera kilka wygodnych metod, które nie są częścią interfejsu proto-plus. Można jednak łatwo uzyskać do nich dostęp, konwertując wiadomość proto-plus na jej odpowiednik 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 przejściem na najnowszą wersję biblioteki, zgłoś problem w naszym narzędziu do śledzenia.