use_proto_plusพารามิเตอร์การกำหนดค่าช่วยให้คุณระบุได้ว่าต้องการให้ไลบรารีแสดงผลเป็นข้อความ proto-plus หรือข้อความ protobuf ดูรายละเอียดเกี่ยวกับวิธี
ตั้งค่าพารามิเตอร์นี้ได้ที่เอกสารการกำหนดค่า
ส่วนนี้จะอธิบายผลกระทบด้านประสิทธิภาพของแต่ละตัวเลือก เพื่อให้คุณเลือกแนวทางที่ดีที่สุดสำหรับแอปพลิเคชันได้
ข้อความ Proto-plus กับข้อความ Protocol Buffer
ไปป์ไลน์เครื่องมือสร้างโค้ดจะผสานรวม 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
เวลาที่ใช้ในการทำ Conversion ประเภทนี้มีผลต่อประสิทธิภาพมากพอที่คุณควรตัดสินใจว่าจะใช้ข้อความ proto-plus หรือ protobuf โดยพิจารณาจากความต้องการของแอปพลิเคชัน
กรณีการใช้งานสำหรับข้อความ proto-plus และ Protobuf
- กรณีการใช้งานข้อความ Proto-plus
- Proto-plus มีการปรับปรุงด้านสรีรศาสตร์หลายอย่างเมื่อเทียบกับข้อความ Protobuf จึงเหมาะอย่างยิ่งสำหรับการเขียนโค้ดที่อ่านได้และบำรุงรักษาได้ เนื่องจากแสดงออบเจ็กต์ Python มาตรฐาน จึงใช้งานและทำความเข้าใจได้ง่ายกว่า
- กรณีการใช้งานข้อความ Protobuf
- ใช้ Protobuf สำหรับกรณีการใช้งานที่คำนึงถึงประสิทธิภาพ โดยเฉพาะในแอปที่
ต้องประมวลผลรายงานขนาดใหญ่อย่างรวดเร็ว หรือสร้างคำขอเปลี่ยนแปลงที่มี
การดำเนินการจำนวนมาก เช่น ด้วย
BatchJobServiceหรือOfflineUserDataJobService
เปลี่ยนประเภทข้อความแบบไดนามิก
หลังจากเลือกประเภทข้อความที่เหมาะสมสำหรับแอปแล้ว คุณอาจพบว่า
ต้องใช้ข้อความอีกประเภทหนึ่งสำหรับเวิร์กโฟลว์ที่เฉพาะเจาะจง ในกรณีนี้ คุณสามารถ
สลับระหว่างโฆษณาทั้ง 2 ประเภทแบบไดนามิกได้โดยใช้ยูทิลิตีที่ไคลเอ็นต์
ไลบรารีมีให้ ใช้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 จัดเตรียมไว้
ออกแบบมาเพื่อใช้อินสแตนซ์ข้อความ Protobuf เมื่อใช้ข้อความ 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)
Enum
Enums ที่แสดงโดยข้อความ proto-plus เป็นอินสแตนซ์ของประเภท enum ในตัวของ Python จึงรับช่วงเมธอดอำนวยความสะดวกจำนวนหนึ่ง
การดึงข้อมูลประเภท Enum
เมื่อใช้เมธอด GoogleAdsClient.get_type เพื่อดึงข้อมูล Enum ข้อความ
ที่แสดงผลจะแตกต่างกันเล็กน้อยโดยขึ้นอยู่กับว่าคุณใช้ข้อความ
proto-plus หรือ protobuf เช่น
- ข้อความ Proto-plus
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
- ข้อความ Protobuf
val = client.get_type("CampaignStatusEnum").PAUSED
เพื่อให้การดึงข้อมูล Enum ง่ายขึ้น เราจึงมีแอตทริบิวต์ความสะดวกในอินสแตนซ์ของ
GoogleAdsClient ซึ่งมีอินเทอร์เฟซที่สอดคล้องกันไม่ว่าคุณจะใช้ข้อความประเภทใดก็ตาม
val = client.enums.CampaignStatusEnum.PAUSED
การดึงค่า enum
บางครั้งการทราบค่าหรือรหัสฟิลด์ของ Enum ที่กำหนดก็มีประโยชน์ เช่น 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"))
การดึงชื่อ Enum
บางครั้งการทราบชื่อของฟิลด์ Enum ก็มีประโยชน์ ตัวอย่างเช่น เมื่ออ่านออบเจ็กต์จาก API คุณอาจต้องการทราบว่าสถานะแคมเปญใดที่สอดคล้องกับจำนวนเต็ม 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
จากนั้นใน 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()
เครื่องมือติดตามปัญหา
หากมีข้อสงสัยเกี่ยวกับการเปลี่ยนแปลงเหล่านี้หรือปัญหาในการย้ายข้อมูลไปยัง ไลบรารีเวอร์ชันล่าสุด โปรดรายงานปัญหาใน เครื่องมือติดตามปัญหา