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
จากการวิเคราะห์ประสิทธิภาพ เราพบว่าเวลาที่ใช้ในการทำ Conversion ประเภทนี้ส่งผลต่อประสิทธิภาพมากพอที่ผู้ใช้ควรตัดสินใจว่าจะใช้ข้อความ 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
เราได้เพิ่มแอตทริบิวต์ความสะดวกในอินสแตนซ์ GoogleAdsClient
เพื่อให้การดึงข้อมูล Enum ง่ายขึ้น ซึ่งมีอินเทอร์เฟซที่สอดคล้องกันไม่ว่าคุณจะใช้ข้อความประเภทใดก็ตาม
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 # To read the value of campaign status print(status_enum.CampaignStatus.Value(campaign.status))
การดึงชื่อ Enum
บางครั้งการทราบชื่อของฟิลด์ Enum ก็มีประโยชน์ เช่น เมื่ออ่านออบเจ็กต์จาก API คุณอาจต้องการทราบว่าสถานะแคมเปญใดที่
int 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 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 simply check the message for # truthiness. is_empty = bool(campaign) is_empty = not 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
ที่กำหนดว่ามีการตั้งค่าฟิลด์ใน
ข้อความหรือไม่ แม้ว่าจะตั้งค่าเป็นค่าเริ่มต้นก็ตาม
วิธีการของข้อความ Protobuf
อินเทอร์เฟซข้อความ protobuf มีเมธอดอำนวยความสะดวกบางอย่างที่ไม่ได้เป็นส่วนหนึ่งของอินเทอร์เฟซ proto-plus แต่คุณสามารถเข้าถึงเมธอดเหล่านั้นได้ง่ายๆ โดยการแปลงข้อความ proto-plus เป็นข้อความ 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())
เครื่องมือติดตามปัญหา
หากมีข้อสงสัยเกี่ยวกับการเปลี่ยนแปลงเหล่านี้หรือปัญหาในการย้ายข้อมูลไปยังไลบรารีเวอร์ชันล่าสุด โปรดยื่นปัญหาในเครื่องมือติดตามปัญหา