pulpie / examples /05_protobuf_dev.html
bhavnicksm's picture
Pulpie vs Dripper race demo: streaming side-by-side extraction, Feyn styling
fc96d89
Raw
History Blame Contribute Delete
111 kB
<!doctype html><html itemscope itemtype=http://schema.org/WebPage lang=en class=no-js><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name=robots content="index, follow"><link rel="shortcut icon" href=/favicons/favicon.ico><link rel=apple-touch-icon href=/favicons/apple-touch-icon-180x180.png sizes=180x180><link rel=icon type=image/png href=/favicons/favicon-16x16.png sizes=16x16><link rel=icon type=image/png href=/favicons/favicon-32x32.png sizes=32x32><link rel=icon type=image/png href=/favicons/android-36x36.png sizes=36x36><link rel=icon type=image/png href=/favicons/android-48x48.png sizes=48x48><link rel=icon type=image/png href=/favicons/android-72x72.png sizes=72x72><link rel=icon type=image/png href=/favicons/android-96x96.png sizes=96x96><link rel=icon type=image/png href=/favicons/android-144x144.png sizes=144x144><link rel=icon type=image/png href=/favicons/android-192x192.png sizes=192x192><title>Protocol Buffer Basics: Python | Protocol Buffers Documentation</title>
<meta name=description content="A basic Python programmers introduction to working with protocol buffers."><meta property="og:title" content="Protocol Buffer Basics: Python"><meta property="og:description" content="A basic Python programmers introduction to working with protocol buffers."><meta property="og:type" content="article"><meta property="og:url" content="https://protobuf.dev/getting-started/pythontutorial/"><meta property="article:section" content="getting-started"><meta itemprop=name content="Protocol Buffer Basics: Python"><meta itemprop=description content="A basic Python programmers introduction to working with protocol buffers."><meta itemprop=wordCount content="2851"><meta itemprop=keywords content><meta name=twitter:card content="summary"><meta name=twitter:title content="Protocol Buffer Basics: Python"><meta name=twitter:description content="A basic Python programmers introduction to working with protocol buffers."><link rel=preload href=/scss/main.min.4f1376b1ff36b4e1500eb32a3dc4db0108d6e7f4e3a5c5edcfa32e8114b87427.css as=style integrity="sha256-TxN2sf82tOFQDrMqPcTbAQjW5/TjpcXtz6MugRS4dCc=" crossorigin=anonymous><link href=/scss/main.min.4f1376b1ff36b4e1500eb32a3dc4db0108d6e7f4e3a5c5edcfa32e8114b87427.css rel=stylesheet integrity="sha256-TxN2sf82tOFQDrMqPcTbAQjW5/TjpcXtz6MugRS4dCc=" crossorigin=anonymous><script src=https://code.jquery.com/jquery-3.7.1.min.js integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" crossorigin=anonymous></script><script async src="https://www.googletagmanager.com/gtag/js?id=G-5L8P8GRN4Y"></script><script>var doNotTrack=!1,dnt;if(!1&&(dnt=navigator.doNotTrack||window.doNotTrack||navigator.msDoNotTrack,doNotTrack=dnt=="1"||dnt=="yes"),!doNotTrack){window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments)}gtag("js",new Date),gtag("config","G-5L8P8GRN4Y")}</script></head><body class=td-page><header><nav class="td-navbar js-navbar-scroll" data-bs-theme=dark><div class="container-fluid flex-column flex-md-row"><a class=navbar-brand href=/><span class="navbar-brand__logo navbar-logo"></span><span class=navbar-brand__name>Protocol Buffers Documentation</span></a><div class="td-navbar-nav-scroll ms-md-auto" id=main_navbar><ul class=navbar-nav></ul></div><div class="d-none d-lg-block"><div class=td-search><div class=td-search__icon></div><input type=search class="td-search__input form-control td-search-input" placeholder="Search this site…" aria-label="Search this site…" autocomplete=off></div></div></div></nav></header><div class="container-fluid td-outer"><div class=td-main><div class="row flex-xl-nowrap"><aside class="col-12 col-md-3 col-xl-2 td-sidebar d-print-none"><div id=td-sidebar-menu class=td-sidebar__inner><div id=content-mobile><form class="td-sidebar__search d-flex align-items-center"><div class=td-search><div class=td-search__icon></div><input type=search class="td-search__input form-control td-search-input" placeholder="Search this site…" aria-label="Search this site…" autocomplete=off></div><button class="btn btn-link td-sidebar__toggle d-md-none p-0 ms-3 fas fa-bars" type=button data-bs-toggle=collapse data-bs-target=#td-section-nav aria-controls=td-section-nav aria-expanded=false aria-label="Toggle section navigation"></button></form></div><div id=content-desktop></div><nav class="td-sidebar-nav collapse td-sidebar-nav--search-disabled" id=td-section-nav><ul class="td-sidebar-nav__section pe-md-3 ul-0"><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child active-path" id=m--li><a href=/ class="align-left ps-0 td-sidebar-link td-sidebar-link__section tree-root" id=m-><span>Protocol Buffers</span></a><ul class=ul-1><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-overview-li><a href=/overview/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-overview><span>Overview</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-installation-li><a href=/installation/ title="Protocol Buffer Compiler Installation" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-installation><span>Protoc Installation</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-news-li><a href=/news/ class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-news><span>News</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-programming-guides-li><a href=/programming-guides/ class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-programming-guides><span>Programming Guides</span></a><ul class="ul-2 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guideseditions-li><a href=/programming-guides/editions/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guideseditions><span>Language Guide (editions)</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesproto2-li><a href=/programming-guides/proto2/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesproto2><span>Language Guide (proto 2)</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesproto3-li><a href=/programming-guides/proto3/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesproto3><span>Language Guide (proto 3)</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesproto-limits-li><a href=/programming-guides/proto-limits/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesproto-limits><span>Proto Limits</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesstyle-li><a href=/programming-guides/style/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesstyle><span>Style Guide</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesenum-li><a href=/programming-guides/enum/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesenum><span>Enum Behavior</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesencoding-li><a href=/programming-guides/encoding/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesencoding><span>Encoding</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesjson-li><a href=/programming-guides/json/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesjson><span>ProtoJSON Format</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidestechniques-li><a href=/programming-guides/techniques/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidestechniques><span>Techniques</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesaddons-li><a href=/programming-guides/addons/ title="Third-Party Add-ons" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesaddons><span>Add-ons</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesextension_declarations-li><a href=/programming-guides/extension_declarations/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesextension_declarations><span>Extension Declarations</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesfield_presence-li><a href=/programming-guides/field_presence/ title="Application Note: Field Presence" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesfield_presence><span>Field Presence</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidessymbol_visibility-li><a href=/programming-guides/symbol_visibility/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidessymbol_visibility><span>Symbol Visibility</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesserialization-not-canonical-li><a href=/programming-guides/serialization-not-canonical/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesserialization-not-canonical><span>Proto Serialization Is Not Canonical</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesdeserialize-debug-li><a href=/programming-guides/deserialize-debug/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesdeserialize-debug><span>Deserializing Debug Proto Representations</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-editions-li><a href=/editions/ class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-editions><span>Protobuf Editions</span></a><ul class="ul-2 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-editionsoverview-li><a href=/editions/overview/ title="Protobuf Editions Overview" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-editionsoverview><span>Overview</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-editionsfeatures-li><a href=/editions/features/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-editionsfeatures><span>Feature Settings for Editions</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-editionsimplementation-li><a href=/editions/implementation/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-editionsimplementation><span>Implementing Editions Support</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-design-decisions-li><a href=/design-decisions/ title="Protobuf Team Design Decisions" class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-design-decisions><span>Design Decisions</span></a><ul class="ul-2 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-design-decisionsnullable-getters-setters-li><a href=/design-decisions/nullable-getters-setters/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-design-decisionsnullable-getters-setters><span>No Nullable Setters/Getters Support</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-best-practices-li><a href=/best-practices/ class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-best-practices><span>Proto Best Practices</span></a><ul class="ul-2 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-best-practicesno-cargo-cults-li><a href=/best-practices/no-cargo-cults/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-best-practicesno-cargo-cults><span>Avoid Cargo Culting</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-best-practicesdos-donts-li><a href=/best-practices/dos-donts/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-best-practicesdos-donts><span>Proto Best Practices</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-best-practices1-1-1-li><a href=/best-practices/1-1-1/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-best-practices1-1-1><span>1-1-1 Best Practice</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child active-path" id=m-getting-started-li><a href=/getting-started/ class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-getting-started><span>Tutorials</span></a><ul class="ul-2 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-getting-startedcpptutorial-li><a href=/getting-started/cpptutorial/ title="Protocol Buffer Basics: C++" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-getting-startedcpptutorial><span>C++</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-getting-startedcsharptutorial-li><a href=/getting-started/csharptutorial/ title="Protocol Buffer Basics: C#" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-getting-startedcsharptutorial><span>C#</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-getting-starteddarttutorial-li><a href=/getting-started/darttutorial/ title="Protocol Buffer Basics: Dart" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-getting-starteddarttutorial><span>Dart</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-getting-startedgotutorial-li><a href=/getting-started/gotutorial/ title="Protocol Buffer Basics: Go" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-getting-startedgotutorial><span>Go</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-getting-startedjavatutorial-li><a href=/getting-started/javatutorial/ title="Protocol Buffer Basics: Java" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-getting-startedjavatutorial><span>Java</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-getting-startedkotlintutorial-li><a href=/getting-started/kotlintutorial/ title="Protocol Buffer Basics: Kotlin" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-getting-startedkotlintutorial><span>Kotlin</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child active-path" id=m-getting-startedpythontutorial-li><a href=/getting-started/pythontutorial/ title="Protocol Buffer Basics: Python" class="align-left ps-0 active td-sidebar-link td-sidebar-link__page" id=m-getting-startedpythontutorial><span class=td-sidebar-nav-active-item>Python</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-reference-li><a href=/reference/ class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-reference><span>Reference Guides</span></a><ul class="ul-2 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referencecpp-li><a href=/reference/cpp/ title="C++ Reference" class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-referencecpp><span>C++</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencecppcpp-generated-li><a href=/reference/cpp/cpp-generated/ title="C++ Generated Code Guide" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencecppcpp-generated><span>Generated Code Guide</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencecppstring-view-li><a href=/reference/cpp/string-view/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencecppstring-view><span>String View APIs</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencecpparenas-li><a href=/reference/cpp/arenas/ title="C++ Arena Allocation Guide" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencecpparenas><span>Arena Allocation Guide</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencecppabseil-li><a href=/reference/cpp/abseil/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencecppabseil><span>Abseil Support</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencecppapi-docs-link-li><a href=/reference/cpp/api-docs/ target=_blank rel=noopener class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencecppapi-docs-link><span>C++ API</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referencecsharp-li><a href=/reference/csharp/ title="C# Reference" class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-referencecsharp><span>C#</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencecsharpcsharp-generated-li><a href=/reference/csharp/csharp-generated/ title="C# Generated Code Guide" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencecsharpcsharp-generated><span>Generated Code Guide</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencecsharpapi-docs-link-li><a href=/reference/csharp/api-docs target=_blank rel=noopener class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencecsharpapi-docs-link><span>C# API</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referencedart-li><a href=/reference/dart/ title="Dart Reference" class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-referencedart><span>Dart</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencedartdart-generated-li><a href=/reference/dart/dart-generated/ title="Dart Generated Code" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencedartdart-generated><span>Generated Code</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencedartapi-docs-link-li><a href=https://pub.dartlang.org/documentation/protobuf target=_blank rel=noopener class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencedartapi-docs-link><span>Dart API</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referencego-li><a href=/reference/go/ title="Go Reference" class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-referencego><span>Go</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencegogo-generated-li><a href=/reference/go/go-generated/ title="Go Generated Code Guide (Open)" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencegogo-generated><span>Generated Code Guide (Open)</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencegogo-generated-opaque-li><a href=/reference/go/go-generated-opaque/ title="Go Generated Code Guide (Opaque)" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencegogo-generated-opaque><span>Generated Code Guide (Opaque)</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencegofaq-li><a href=/reference/go/faq/ title="Go FAQ" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencegofaq><span>FAQ</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencegosize-li><a href=/reference/go/size/ title="Go Size Semantics" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencegosize><span>Size Semantics</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencegoapi-docs-link-li><a href=https://pkg.go.dev/google.golang.org/protobuf/proto target=_blank rel=noopener class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencegoapi-docs-link><span>Go API</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencegoopaque-migration-li><a href=/reference/go/opaque-migration/ title="Go Opaque API Migration" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencegoopaque-migration><span>Opaque API Migration</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencegoopaque-migration-manual-li><a href=/reference/go/opaque-migration-manual/ title="Go Opaque API: Manual Migration" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencegoopaque-migration-manual><span>Opaque API: Manual Migration</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencegoopaque-faq-li><a href=/reference/go/opaque-faq/ title="Go Opaque API FAQ" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencegoopaque-faq><span>Opaque API FAQ</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referencejava-li><a href=/reference/java/ title="Java Reference" class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-referencejava><span>Java</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencejavajava-generated-li><a href=/reference/java/java-generated/ title="Java Generated Code Guide" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencejavajava-generated><span>Generated Code Guide</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencejavajava-proto-names-li><a href=/reference/java/java-proto-names/ title="Java Proto Names" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencejavajava-proto-names><span>Generated Proto Names</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencejavaapi-docs-link-li><a href=/reference/java/api-docs/overview-summary.html target=_blank rel=noopener class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencejavaapi-docs-link><span>Java API</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referencekotlin-li><a href=/reference/kotlin/ title="Kotlin Reference" class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-referencekotlin><span>Kotlin</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencekotlinapi-docs-li><a href=/reference/kotlin/api-docs/ title="Kotlin Reference" class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-referencekotlinapi-docs><span>Kotlin</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencekotlinkotlin-generated-li><a href=/reference/kotlin/kotlin-generated/ title="Kotlin Generated Code Guide" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencekotlinkotlin-generated><span>Generated Code Guide</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referenceobjective-c-li><a href=/reference/objective-c/ title="Objective-C Reference" class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-referenceobjective-c><span>Objective-C</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referenceobjective-cobjective-c-generated-li><a href=/reference/objective-c/objective-c-generated/ title="Objective-C Generated Code Guide" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referenceobjective-cobjective-c-generated><span>Generated Code Guide</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referencephp-li><a href=/reference/php/ title="PHP Reference" class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-referencephp><span>PHP</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencephpphp-generated-li><a href=/reference/php/php-generated/ title="PHP Generated Code Guide" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencephpphp-generated><span>Generated Code Guide</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencephpapi-docs-link-li><a href=/reference/php/api-docs/ target=_blank rel=noopener class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencephpapi-docs-link><span>PHP API</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referencepython-li><a href=/reference/python/ title="Python Reference" class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-referencepython><span>Python</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencepythonpython-generated-li><a href=/reference/python/python-generated/ title="Python Generated Code Guide" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencepythonpython-generated><span>Generated Code Guide</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencepythonpython-comparison-li><a href=/reference/python/python-comparison/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencepythonpython-comparison><span>Python Comparison</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencepythonapi-docs-link-li><a href=https://googleapis.dev/python/protobuf/latest/ target=_blank rel=noopener class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencepythonapi-docs-link><span>Python API</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referenceruby-li><a href=/reference/ruby/ title="Ruby Reference" class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-referenceruby><span>Ruby</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencerubyruby-generated-li><a href=/reference/ruby/ruby-generated/ title="Ruby Generated Code Guide" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencerubyruby-generated><span>Generated Code Guide</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referencerust-li><a href=/reference/rust/ title="Rust Reference" class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-referencerust><span>Rust</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencerustrust-generated-li><a href=/reference/rust/rust-generated/ title="Rust Generated Code Guide" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencerustrust-generated><span>Generated Code Guide</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencerustrust-redaction-li><a href=/reference/rust/rust-redaction/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencerustrust-redaction><span>Redaction in Rust</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencerustbuilding-rust-protos-li><a href=/reference/rust/building-rust-protos/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencerustbuilding-rust-protos><span>Building Rust Protos</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencerustrust-design-decisions-li><a href=/reference/rust/rust-design-decisions/ title="Rust Proto Design Decisions" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referencerustrust-design-decisions><span>Design Decisions</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referenceprotobuf-li><a href=/reference/protobuf/ title="Protocol Buffers Reference" class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-referenceprotobuf><span>Protocol Buffers</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referenceprotobufedition-2023-spec-li><a href=/reference/protobuf/edition-2023-spec/ title="Protocol Buffers Edition 2023 Language Specification" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referenceprotobufedition-2023-spec><span>2023 Language Specification</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referenceprotobufproto2-spec-li><a href=/reference/protobuf/proto2-spec/ title="Protocol Buffers Language Specification (Proto2 Syntax)" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referenceprotobufproto2-spec><span>Language Specification (Proto2 Syntax)</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referenceprotobufedition-2024-spec-li><a href=/reference/protobuf/edition-2024-spec/ title="Protocol Buffers Edition 2024 Language Specification" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referenceprotobufedition-2024-spec><span>2024 Language Specification</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referenceprotobufproto3-spec-li><a href=/reference/protobuf/proto3-spec/ title="Protocol Buffers Language Specification (Proto3)" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referenceprotobufproto3-spec><span>Language Specification (Proto3)</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referenceprotobuftextformat-spec-li><a href=/reference/protobuf/textformat-spec/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referenceprotobuftextformat-spec><span>Text Format Language Specification</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referenceprotobufmime-types-li><a href=/reference/protobuf/mime-types/ title="Protocol Buffer MIME Types" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referenceprotobufmime-types><span>MIME Types</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referenceprotobufgoogleprotobuf-li><a href=/reference/protobuf/google.protobuf/ title="Protocol Buffers Well-Known Types" class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referenceprotobufgoogleprotobuf><span>Well-Known Types</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referenceother-li><a href=/reference/other/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-referenceother><span>Other Languages</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-support-li><a href=/support/ class="align-left ps-0 td-sidebar-link td-sidebar-link__section" id=m-support><span>Support</span></a><ul class="ul-2 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-supportversion-support-li><a href=/support/version-support/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-supportversion-support><span>Version Support</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-supportdebugging-playbook-li><a href=/support/debugging-playbook/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-supportdebugging-playbook><span>Debugging</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-supportmigration-li><a href=/support/migration/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-supportmigration><span>Migration Guide</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-supportcross-version-runtime-guarantee-li><a href=/support/cross-version-runtime-guarantee/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-supportcross-version-runtime-guarantee><span>Cross-Version Runtime Guarantee</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-downloads-li><a href=/downloads/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-downloads><span>Downloads</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-history-li><a href=/history/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-history><span>History</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-forum-link-li><a href=https://groups.google.com/g/protobuf target=_blank rel=noopener class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-forum-link><span>Forum</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-navbar-li><a href=/navbar/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-navbar><span></span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-search-li><a href=/search/ class="align-left ps-0 td-sidebar-link td-sidebar-link__page" id=m-search><span>Search Results</span></a></li></ul></li></ul></nav></div></aside><aside class="d-none d-xl-block col-xl-2 td-sidebar-toc d-print-none"><div class="td-page-meta ml-2 pb-1 pt-2 mb-0"><a href=https://github.com/protocolbuffers/protocolbuffers.github.io/tree/main/content/getting-started/pythontutorial.md class=td-page-meta--view target=_blank rel=noopener><i class="fa-solid fa-file-lines fa-fw"></i> View page source</a>
<a href=https://github.com/protocolbuffers/protocolbuffers.github.io/edit/main/content/getting-started/pythontutorial.md class=td-page-meta--edit target=_blank rel=noopener><i class="fa-solid fa-pen-to-square fa-fw"></i> Edit this page</a>
<a href="https://github.com/protocolbuffers/protocolbuffers.github.io/new/main/content/getting-started/pythontutorial.md?filename=change-me.md&amp;value=---%0Atitle%3A+%22Long+Page+Title%22%0AlinkTitle%3A+%22Short+Nav+Title%22%0Aweight%3A+100%0Adescription%3A+%3E-%0A+++++Page+description+for+heading+and+indexes.%0A---%0A%0A%23%23+Heading%0A%0AEdit+this+template+to+create+your+new+page.%0A%0A%2A+Give+it+a+good+name%2C+ending+in+%60.md%60+-+e.g.+%60getting-started.md%60%0A%2A+Edit+the+%22front+matter%22+section+at+the+top+of+the+page+%28weight+controls+how+its+ordered+amongst+other+pages+in+the+same+directory%3B+lowest+number+first%29.%0A%2A+Add+a+good+commit+message+at+the+bottom+of+the+page+%28%3C80+characters%3B+use+the+extended+description+field+for+more+detail%29.%0A%2A+Create+a+new+branch+so+you+can+preview+your+new+file+and+request+a+review+via+Pull+Request.%0A" class=td-page-meta--child target=_blank rel=noopener><i class="fa-solid fa-pen-to-square fa-fw"></i> Create child page</a>
<a href="https://github.com/protocolbuffers/protocolbuffers.github.io/issues/new?title=Protocol%20Buffer%20Basics:%20Python" class=td-page-meta--issue target=_blank rel=noopener><i class="fa-solid fa-list-check fa-fw"></i> Create documentation issue</a>
<a href=https://github.com/protocolbuffers/protobuf/issues/new class=td-page-meta--project-issue target=_blank rel=noopener><i class="fa-solid fa-list-check fa-fw"></i> Create project issue</a></div><div class=td-toc><nav id=TableOfContents><ul><li><a href=#problem-domain>The Problem Domain</a></li><li><a href=#example-code>Where to Find the Example Code</a></li><li><a href=#protocol-format>Defining Your Protocol Format</a></li><li><a href=#compiling-protocol-buffers>Compiling Your Protocol Buffers</a></li><li><a href=#protobuf-api>The Protocol Buffer API</a><ul><li><a href=#enums>Enums</a></li><li><a href=#standard-message-methods>Standard Message Methods</a></li><li><a href=#parsing-serialization>Parsing and Serialization</a></li></ul></li><li><a href=#writing-a-message>Writing a Message</a></li><li><a href=#reading-a-message>Reading a Message</a></li><li><a href=#extending-a-protobuf>Extending a Protocol Buffer</a></li><li><a href=#advanced-usage>Advanced Usage</a></li></ul></nav></div></aside><main class="col-12 col-md-9 col-xl-8 ps-md-5" role=main><nav aria-label=breadcrumb class=td-breadcrumbs><ol class=breadcrumb><li class=breadcrumb-item><a href=/getting-started/>Tutorials</a></li><li class="breadcrumb-item active" aria-current=page>Python</li></ol></nav><div class=td-content><h1>Protocol Buffer Basics: Python</h1><div class=lead>A basic Python programmers introduction to working with protocol buffers.</div><header class=article-meta></header><p>This tutorial provides a basic Python programmer&rsquo;s introduction to working with
protocol buffers. By walking through creating a simple example application, it
shows you how to</p><ul><li>Define message formats in a <code>.proto</code> file.</li><li>Use the protocol buffer compiler.</li><li>Use the Python protocol buffer API to write and read messages.</li></ul><p>This isn&rsquo;t a comprehensive guide to using protocol buffers in Python. For more
detailed reference information, see the
<a href=/programming-guides/proto2>Protocol Buffer Language Guide (proto2)</a>,
the
<a href=/programming-guides/proto3>Protocol Buffer Language Guide (proto3)</a>,
the <a href=https://googleapis.dev/python/protobuf/latest/>Python API Reference</a>, the
<a href=/reference/python/python-generated>Python Generated Code Guide</a>,
and the
<a href=/programming-guides/encoding>Encoding Reference</a>.</p><h2 id=problem-domain>The Problem Domain</h2><p>The example we&rsquo;re going to use is a very simple &ldquo;address book&rdquo; application that
can read and write people&rsquo;s contact details to and from a file. Each person in
the address book has a name, an ID, an email address, and a contact phone
number.</p><p>How do you serialize and retrieve structured data like this? There are a few
ways to solve this problem:</p><ul><li>Use Python pickling. This is the default approach since it&rsquo;s built into the
language, but it doesn&rsquo;t deal well with schema evolution, and also doesn&rsquo;t
work very well if you need to share data with applications written in C++ or
Java.</li><li>You can invent an ad-hoc way to encode the data items into a single
string &ndash; such as encoding 4 ints as &ldquo;12:3:-23:67&rdquo;. This is a simple and
flexible approach, although it does require writing one-off encoding and
parsing code, and the parsing imposes a small run-time cost. This works best
for encoding very simple data.</li><li>Serialize the data to XML. This approach can be very attractive since XML is
(sort of) human readable and there are binding libraries for lots of
languages. This can be a good choice if you want to share data with other
applications/projects. However, XML is notoriously space intensive, and
encoding/decoding it can impose a huge performance penalty on applications.
Also, navigating an XML DOM tree is considerably more complicated than
navigating simple fields in a class normally would be.</li></ul><p>Instead of these options, you can use protocol buffers. Protocol buffers are the
flexible, efficient, automated solution to solve exactly this problem. With
protocol buffers, you write a <code>.proto</code> description of the data structure you
wish to store. From that, the protocol buffer compiler creates a class that
implements automatic encoding and parsing of the protocol buffer data with an
efficient binary format. The generated class provides getters and setters for
the fields that make up a protocol buffer and takes care of the details of
reading and writing the protocol buffer as a unit. Importantly, the protocol
buffer format supports the idea of extending the format over time in such a way
that the code can still read data encoded with the old format.</p><h2 id=example-code>Where to Find the Example Code</h2><p>The example code is included in the source code package, under the &ldquo;examples&rdquo;
directory. <a href=/downloads>Download it here.</a></p><h2 id=protocol-format>Defining Your Protocol Format</h2><p>To create your address book application, you&rsquo;ll need to start with a <code>.proto</code>
file. The definitions in a <code>.proto</code> file are simple: you add a <em>message</em> for
each data structure you want to serialize, then specify a name and a type for
each field in the message. Here is the <code>.proto</code> file that defines your messages,
<code>addressbook.proto</code>.</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-proto data-lang=proto><span style=display:flex><span><span style=color:#000>edition</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#4e9a06>&#34;2023&#34;</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span><span style=color:#204a87;font-weight:700>package</span> <span style=color:#000>tutorial</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span><span style=color:#204a87;font-weight:700>message</span> <span style=color:#000>Person</span> <span style=color:#000;font-weight:700>{</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#204a87;font-weight:700>string</span> <span style=color:#000>name</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>1</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#204a87;font-weight:700>int32</span> <span style=color:#000>id</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>2</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#204a87;font-weight:700>string</span> <span style=color:#000>email</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>3</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#204a87;font-weight:700>enum</span> <span style=color:#000>PhoneType</span> <span style=color:#000;font-weight:700>{</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#000>PHONE_TYPE_UNSPECIFIED</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>0</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#000>PHONE_TYPE_MOBILE</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>1</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#000>PHONE_TYPE_HOME</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>2</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#000>PHONE_TYPE_WORK</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>3</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#000;font-weight:700>}</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#204a87;font-weight:700>message</span> <span style=color:#000>PhoneNumber</span> <span style=color:#000;font-weight:700>{</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#204a87;font-weight:700>string</span> <span style=color:#000>number</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>1</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#000>PhoneType</span> <span style=color:#000>type</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>2</span> <span style=color:#000;font-weight:700>[</span><span style=color:#204a87;font-weight:700>default</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>PHONE_TYPE_HOME</span><span style=color:#000;font-weight:700>];</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#000;font-weight:700>}</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#204a87;font-weight:700>repeated</span> <span style=color:#000>PhoneNumber</span> <span style=color:#000>phones</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>4</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span><span style=color:#000;font-weight:700>}</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span><span style=color:#204a87;font-weight:700>message</span> <span style=color:#000>AddressBook</span> <span style=color:#000;font-weight:700>{</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#204a87;font-weight:700>repeated</span> <span style=color:#000>Person</span> <span style=color:#000>people</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>1</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000>
</span></span></span><span style=display:flex><span><span style=color:#a40000></span><span style=color:#000;font-weight:700>}</span><span style=color:#a40000>
</span></span></span></code></pre></div><p>As you can see, the syntax is similar to C++ or Java. Let&rsquo;s go through each part
of the file and see what it does.</p><p>The <code>.proto</code> file starts with a package declaration, which helps to prevent
naming conflicts between different projects. In Python, packages are normally
determined by directory structure, so the <code>package</code> you define in your <code>.proto</code>
file will have no effect on the generated code. However, you should still
declare one to avoid name collisions in the Protocol Buffers name space as well
as in non-Python languages.</p><p>Next, you have your message definitions. A message is just an aggregate
containing a set of typed fields. Many standard simple data types are available
as field types, including <code>bool</code>, <code>int32</code>, <code>float</code>, <code>double</code>, and <code>string</code>. You
can also add further structure to your messages by using other message types as
field types &ndash; in the above example the <code>Person</code> message contains <code>PhoneNumber</code>
messages, while the <code>AddressBook</code> message contains <code>Person</code> messages. You can
even define message types nested inside other messages &ndash; as you can see, the
<code>PhoneNumber</code> type is defined inside <code>Person</code>. You can also define <code>enum</code> types
if you want one of your fields to have one of a predefined list of values &ndash;
here you want to specify that a phone number can be one of the following phone
types: <code>PHONE_TYPE_MOBILE</code>, <code>PHONE_TYPE_HOME</code>, or <code>PHONE_TYPE_WORK</code>.</p><p>The " = 1", " = 2" markers on each element identify the unique &ldquo;tag&rdquo; that field
uses in the binary encoding. Tag numbers 1-15 require one less byte to encode
than higher numbers, so as an optimization you can decide to use those tags for
the commonly used or repeated elements, leaving tags 16 and higher for
less-commonly used optional elements. Each element in a repeated field requires
re-encoding the tag number, so repeated fields are particularly good candidates
for this optimization.</p><p>You&rsquo;ll find a complete guide to writing <code>.proto</code> files &ndash; including all the
possible field types &ndash; in the
<a href=/programming-guides/editions>Protocol Buffer Language Guide</a>.
Don&rsquo;t go looking for facilities similar to class inheritance, though &ndash; protocol
buffers don&rsquo;t do that.</p><h2 id=compiling-protocol-buffers>Compiling Your Protocol Buffers</h2><p>Now that you have a <code>.proto</code>, the next thing you need to do is generate the
classes you&rsquo;ll need to read and write <code>AddressBook</code> (and hence <code>Person</code> and
<code>PhoneNumber</code>) messages. To do this, you need to run the protocol buffer
compiler <code>protoc</code> on your <code>.proto</code>:</p><ol><li><p>If you haven&rsquo;t installed the compiler,
<a href=/downloads>download the package</a> and follow the
instructions in the README.</p></li><li><p>Now run the compiler, specifying the source directory (where your
application&rsquo;s source code lives &ndash; the current directory is used if you
don&rsquo;t provide a value), the destination directory (where you want the
generated code to go; often the same as <code>$SRC_DIR</code>), and the path to your
<code>.proto</code>. In this case, you&mldr;:</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>protoc --proto_path<span style=color:#ce5c00;font-weight:700>=</span><span style=color:#000>$SRC_DIR</span> --python_out<span style=color:#ce5c00;font-weight:700>=</span><span style=color:#000>$DST_DIR</span> <span style=color:#000>$SRC_DIR</span>/addressbook.proto
</span></span></code></pre></div><p>Because you want Python classes, you use the <code>--python_out</code> option &ndash;
similar options are provided for other supported languages.</p><p>Protoc is also able to generate python stubs (<code>.pyi</code>) with <code>--pyi_out</code>.</p></li></ol><p>This generates <code>addressbook_pb2.py</code> (or <code>addressbook_pb2.pyi</code>) in your specified
destination directory.</p><h2 id=protobuf-api>The Protocol Buffer API</h2><p>Unlike when you generate Java and C++ protocol buffer code, the Python protocol
buffer compiler doesn&rsquo;t generate your data access code for you directly. Instead
(as you&rsquo;ll see if you look at <code>addressbook_pb2.py</code>) it generates special
descriptors for all your messages, enums, and fields, and some mysteriously
empty classes, one for each message type:</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:#204a87;font-weight:700>import</span> <span style=color:#000>google3</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>from</span> <span style=color:#000>google.protobuf</span> <span style=color:#204a87;font-weight:700>import</span> <span style=color:#000>descriptor</span> <span style=color:#204a87;font-weight:700>as</span> <span style=color:#000>_descriptor</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>from</span> <span style=color:#000>google.protobuf</span> <span style=color:#204a87;font-weight:700>import</span> <span style=color:#000>descriptor_pool</span> <span style=color:#204a87;font-weight:700>as</span> <span style=color:#000>_descriptor_pool</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>from</span> <span style=color:#000>google.protobuf</span> <span style=color:#204a87;font-weight:700>import</span> <span style=color:#000>runtime_version</span> <span style=color:#204a87;font-weight:700>as</span> <span style=color:#000>_runtime_version</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>from</span> <span style=color:#000>google.protobuf</span> <span style=color:#204a87;font-weight:700>import</span> <span style=color:#000>symbol_database</span> <span style=color:#204a87;font-weight:700>as</span> <span style=color:#000>_symbol_database</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>from</span> <span style=color:#000>google.protobuf.internal</span> <span style=color:#204a87;font-weight:700>import</span> <span style=color:#000>builder</span> <span style=color:#204a87;font-weight:700>as</span> <span style=color:#000>_builder</span>
</span></span><span style=display:flex><span><span style=color:#000>_runtime_version</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>ValidateProtobufRuntimeVersion</span><span style=color:#000;font-weight:700>(</span>
</span></span><span style=display:flex><span> <span style=color:#000>_runtime_version</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>Domain</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>GOOGLE_INTERNAL</span><span style=color:#000;font-weight:700>,</span>
</span></span><span style=display:flex><span> <span style=color:#0000cf;font-weight:700>0</span><span style=color:#000;font-weight:700>,</span>
</span></span><span style=display:flex><span> <span style=color:#0000cf;font-weight:700>20240502</span><span style=color:#000;font-weight:700>,</span>
</span></span><span style=display:flex><span> <span style=color:#0000cf;font-weight:700>0</span><span style=color:#000;font-weight:700>,</span>
</span></span><span style=display:flex><span> <span style=color:#4e9a06>&#39;&#39;</span><span style=color:#000;font-weight:700>,</span>
</span></span><span style=display:flex><span> <span style=color:#4e9a06>&#39;main.proto&#39;</span>
</span></span><span style=display:flex><span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic># @@protoc_insertion_point(imports)</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#000>_sym_db</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>_symbol_database</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>Default</span><span style=color:#000;font-weight:700>()</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#000>DESCRIPTOR</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>_descriptor_pool</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>Default</span><span style=color:#000;font-weight:700>()</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>AddSerializedFile</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>b</span><span style=color:#4e9a06>&#39;</span><span style=color:#4e9a06>\n\n</span><span style=color:#4e9a06>main.proto</span><span style=color:#4e9a06>\x12\x08</span><span style=color:#4e9a06>tutorial</span><span style=color:#4e9a06>\&#34;\xa3\x02\n\x06</span><span style=color:#4e9a06>Person</span><span style=color:#4e9a06>\x12\x0c\n\x04</span><span style=color:#4e9a06>name</span><span style=color:#4e9a06>\x18\x01</span><span style=color:#4e9a06> </span><span style=color:#4e9a06>\x01</span><span style=color:#4e9a06>(</span><span style=color:#4e9a06>\t\x12\n\n\x02</span><span style=color:#4e9a06>id</span><span style=color:#4e9a06>\x18\x02</span><span style=color:#4e9a06> </span><span style=color:#4e9a06>\x01</span><span style=color:#4e9a06>(</span><span style=color:#4e9a06>\x05\x12\r\n\x05\x65</span><span style=color:#4e9a06>mail</span><span style=color:#4e9a06>\x18\x03</span><span style=color:#4e9a06> </span><span style=color:#4e9a06>\x01</span><span style=color:#4e9a06>(</span><span style=color:#4e9a06>\t\x12</span><span style=color:#4e9a06>,</span><span style=color:#4e9a06>\n\x06</span><span style=color:#4e9a06>phones</span><span style=color:#4e9a06>\x18\x04</span><span style=color:#4e9a06> </span><span style=color:#4e9a06>\x03</span><span style=color:#4e9a06>(</span><span style=color:#4e9a06>\x0b\x32\x1c</span><span style=color:#4e9a06>.tutorial.Person.PhoneNumber</span><span style=color:#4e9a06>\x1a</span><span style=color:#4e9a06>X</span><span style=color:#4e9a06>\n\x0b</span><span style=color:#4e9a06>PhoneNumber</span><span style=color:#4e9a06>\x12\x0e\n\x06</span><span style=color:#4e9a06>number</span><span style=color:#4e9a06>\x18\x01</span><span style=color:#4e9a06> </span><span style=color:#4e9a06>\x01</span><span style=color:#4e9a06>(</span><span style=color:#4e9a06>\t\x12\x39\n\x04</span><span style=color:#4e9a06>type</span><span style=color:#4e9a06>\x18\x02</span><span style=color:#4e9a06> </span><span style=color:#4e9a06>\x01</span><span style=color:#4e9a06>(</span><span style=color:#4e9a06>\x0e\x32\x1a</span><span style=color:#4e9a06>.tutorial.Person.PhoneType:</span><span style=color:#4e9a06>\x0f</span><span style=color:#4e9a06>PHONE_TYPE_HOME</span><span style=color:#4e9a06>\&#34;</span><span style=color:#4e9a06>h</span><span style=color:#4e9a06>\n\t</span><span style=color:#4e9a06>PhoneType</span><span style=color:#4e9a06>\x12\x1a\n\x16</span><span style=color:#4e9a06>PHONE_TYPE_UNSPECIFIED</span><span style=color:#4e9a06>\x10\x00\x12\x15\n\x11</span><span style=color:#4e9a06>PHONE_TYPE_MOBILE</span><span style=color:#4e9a06>\x10\x01\x12\x13\n\x0f</span><span style=color:#4e9a06>PHONE_TYPE_HOME</span><span style=color:#4e9a06>\x10\x02\x12\x13\n\x0f</span><span style=color:#4e9a06>PHONE_TYPE_WORK</span><span style=color:#4e9a06>\x10\x03\&#34;</span><span style=color:#4e9a06>/</span><span style=color:#4e9a06>\n\x0b\x41\x64\x64</span><span style=color:#4e9a06>ressBook</span><span style=color:#4e9a06>\x12</span><span style=color:#4e9a06> </span><span style=color:#4e9a06>\n\x06</span><span style=color:#4e9a06>people</span><span style=color:#4e9a06>\x18\x01</span><span style=color:#4e9a06> </span><span style=color:#4e9a06>\x03</span><span style=color:#4e9a06>(</span><span style=color:#4e9a06>\x0b\x32\x10</span><span style=color:#4e9a06>.tutorial.Person&#39;</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#000>_globals</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#204a87>globals</span><span style=color:#000;font-weight:700>()</span>
</span></span><span style=display:flex><span><span style=color:#000>_builder</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>BuildMessageAndEnumDescriptors</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>DESCRIPTOR</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>_globals</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span><span style=color:#000>_builder</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>BuildTopDescriptorsAndMessages</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>DESCRIPTOR</span><span style=color:#000;font-weight:700>,</span> <span style=color:#4e9a06>&#39;google3.main_pb2&#39;</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>_globals</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>if</span> <span style=color:#204a87;font-weight:700>not</span> <span style=color:#000>_descriptor</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>_USE_C_DESCRIPTORS</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#000>DESCRIPTOR</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>_loaded_options</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#204a87;font-weight:700>None</span>
</span></span><span style=display:flex><span> <span style=color:#000>_globals</span><span style=color:#000;font-weight:700>[</span><span style=color:#4e9a06>&#39;_PERSON&#39;</span><span style=color:#000;font-weight:700>]</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>_serialized_start</span><span style=color:#ce5c00;font-weight:700>=</span><span style=color:#0000cf;font-weight:700>25</span>
</span></span><span style=display:flex><span> <span style=color:#000>_globals</span><span style=color:#000;font-weight:700>[</span><span style=color:#4e9a06>&#39;_PERSON&#39;</span><span style=color:#000;font-weight:700>]</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>_serialized_end</span><span style=color:#ce5c00;font-weight:700>=</span><span style=color:#0000cf;font-weight:700>316</span>
</span></span><span style=display:flex><span> <span style=color:#000>_globals</span><span style=color:#000;font-weight:700>[</span><span style=color:#4e9a06>&#39;_PERSON_PHONENUMBER&#39;</span><span style=color:#000;font-weight:700>]</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>_serialized_start</span><span style=color:#ce5c00;font-weight:700>=</span><span style=color:#0000cf;font-weight:700>122</span>
</span></span><span style=display:flex><span> <span style=color:#000>_globals</span><span style=color:#000;font-weight:700>[</span><span style=color:#4e9a06>&#39;_PERSON_PHONENUMBER&#39;</span><span style=color:#000;font-weight:700>]</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>_serialized_end</span><span style=color:#ce5c00;font-weight:700>=</span><span style=color:#0000cf;font-weight:700>210</span>
</span></span><span style=display:flex><span> <span style=color:#000>_globals</span><span style=color:#000;font-weight:700>[</span><span style=color:#4e9a06>&#39;_PERSON_PHONETYPE&#39;</span><span style=color:#000;font-weight:700>]</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>_serialized_start</span><span style=color:#ce5c00;font-weight:700>=</span><span style=color:#0000cf;font-weight:700>212</span>
</span></span><span style=display:flex><span> <span style=color:#000>_globals</span><span style=color:#000;font-weight:700>[</span><span style=color:#4e9a06>&#39;_PERSON_PHONETYPE&#39;</span><span style=color:#000;font-weight:700>]</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>_serialized_end</span><span style=color:#ce5c00;font-weight:700>=</span><span style=color:#0000cf;font-weight:700>316</span>
</span></span><span style=display:flex><span> <span style=color:#000>_globals</span><span style=color:#000;font-weight:700>[</span><span style=color:#4e9a06>&#39;_ADDRESSBOOK&#39;</span><span style=color:#000;font-weight:700>]</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>_serialized_start</span><span style=color:#ce5c00;font-weight:700>=</span><span style=color:#0000cf;font-weight:700>318</span>
</span></span><span style=display:flex><span> <span style=color:#000>_globals</span><span style=color:#000;font-weight:700>[</span><span style=color:#4e9a06>&#39;_ADDRESSBOOK&#39;</span><span style=color:#000;font-weight:700>]</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>_serialized_end</span><span style=color:#ce5c00;font-weight:700>=</span><span style=color:#0000cf;font-weight:700>365</span>
</span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic># @@protoc_insertion_point(module_scope)</span>
</span></span></code></pre></div><p>The important line in each class is <code>__metaclass__ = reflection.GeneratedProtocolMessageType</code>. While the details of how Python
metaclasses work is beyond the scope of this tutorial, you can think of them as
like a template for creating classes. At load time, the
<code>GeneratedProtocolMessageType</code> metaclass uses the specified descriptors to
create all the Python methods you need to work with each message type and adds
them to the relevant classes. You can then use the fully-populated classes in
your code.</p><p>The end effect of all this is that you can use the <code>Person</code> class as if it
defined each field of the <code>Message</code> base class as a regular field. For example,
you could write:</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:#204a87;font-weight:700>import</span> <span style=color:#000>addressbook_pb2</span>
</span></span><span style=display:flex><span><span style=color:#000>person</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>addressbook_pb2</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>Person</span><span style=color:#000;font-weight:700>()</span>
</span></span><span style=display:flex><span><span style=color:#000>person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>id</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>1234</span>
</span></span><span style=display:flex><span><span style=color:#000>person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>name</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#4e9a06>&#34;John Doe&#34;</span>
</span></span><span style=display:flex><span><span style=color:#000>person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>email</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#4e9a06>&#34;jdoe@example.com&#34;</span>
</span></span><span style=display:flex><span><span style=color:#000>phone</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>phones</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>add</span><span style=color:#000;font-weight:700>()</span>
</span></span><span style=display:flex><span><span style=color:#000>phone</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>number</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#4e9a06>&#34;555-4321&#34;</span>
</span></span><span style=display:flex><span><span style=color:#000>phone</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>type</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>addressbook_pb2</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>Person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>PHONE_TYPE_HOME</span>
</span></span></code></pre></div><p>Note that these assignments are not just adding arbitrary new fields to a
generic Python object. If you were to try to assign a field that isn&rsquo;t defined
in the <code>.proto</code> file, an <code>AttributeError</code> would be raised. If you assign a field
to a value of the wrong type, a <code>TypeError</code> will be raised. Also, reading the
value of a field before it has been set returns the default value.</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:#000>person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>no_such_field</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>1</span> <span style=color:#8f5902;font-style:italic># raises AttributeError</span>
</span></span><span style=display:flex><span><span style=color:#000>person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>id</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#4e9a06>&#34;1234&#34;</span> <span style=color:#8f5902;font-style:italic># raises TypeError</span>
</span></span></code></pre></div><p>For more information on exactly what members the protocol compiler generates for
any particular field definition, see the
<a href=/reference/python/python-generated>Python generated code reference</a>.</p><h3 id=enums>Enums</h3><p>Enums are expanded by the metaclass into a set of symbolic constants with
integer values. So, for example, the constant
<code>addressbook_pb2.Person.PhoneType.PHONE_TYPE_WORK</code> has the value 2.</p><h3 id=standard-message-methods>Standard Message Methods</h3><p>Each message class also contains a number of other methods that let you check or
manipulate the entire message, including:</p><ul><li><code>IsInitialized()</code>: checks if all the required fields have been set.</li><li><code>__str__()</code>: returns a human-readable representation of the message,
particularly useful for debugging. (Usually invoked as <code>str(message)</code> or
<code>print message</code>.)</li><li><code>CopyFrom(other_msg)</code>: overwrites the message with the given message&rsquo;s
values.</li><li><code>Clear()</code>: clears all the elements back to the empty state.</li></ul><p>These methods implement the <code>Message</code> interface. For more information, see the
<a href=https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message>complete API documentation for <code>Message</code></a>.</p><h3 id=parsing-serialization>Parsing and Serialization</h3><p>Finally, each protocol buffer class has methods for writing and reading messages
of your chosen type using the protocol buffer
<a href=/programming-guides/encoding>binary format</a>. These
include:</p><ul><li><code>SerializeToString()</code>: serializes the message and returns it as a string.
Note that the bytes are binary, not text; we only use the <code>str</code> type as a
convenient container.</li><li><code>ParseFromString(data)</code>: parses a message from the given string.</li></ul><p>These are just a couple of the options provided for parsing and serialization.
Again, see the
<a href=https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message><code>Message</code> API reference</a>
for a complete list.</p><p>You can also easily serialize messages to and from JSON. The <code>json_format</code>
module provides helpers for this:</p><ul><li><code>MessageToJson(message)</code>: serializes the message to a JSON string.</li><li><code>Parse(json_string, message)</code>: parses a JSON string into the given message.</li></ul><p>For example:</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:#204a87;font-weight:700>from</span> <span style=color:#000>google.protobuf</span> <span style=color:#204a87;font-weight:700>import</span> <span style=color:#000>json_format</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>import</span> <span style=color:#000>addressbook_pb2</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#000>person</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>addressbook_pb2</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>Person</span><span style=color:#000;font-weight:700>()</span>
</span></span><span style=display:flex><span><span style=color:#000>person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>id</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>1234</span>
</span></span><span style=display:flex><span><span style=color:#000>person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>name</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#4e9a06>&#34;John Doe&#34;</span>
</span></span><span style=display:flex><span><span style=color:#000>person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>email</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#4e9a06>&#34;jdoe@example.com&#34;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic># Serialize to JSON</span>
</span></span><span style=display:flex><span><span style=color:#000>json_string</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>json_format</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>MessageToJson</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>person</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic># Parse from JSON</span>
</span></span><span style=display:flex><span><span style=color:#000>new_person</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>addressbook_pb2</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>Person</span><span style=color:#000;font-weight:700>()</span>
</span></span><span style=display:flex><span><span style=color:#000>json_format</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>Parse</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>json_string</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>new_person</span><span style=color:#000;font-weight:700>)</span>
</span></span></code></pre></div><div class="alert alert-warning" role=alert><h4 class=alert-heading>Important</h4><strong>Protocol Buffers and Object Oriented Design</strong>
Protocol buffer classes are basically data holders (like structs in C) that
don&rsquo;t provide additional functionality; they don&rsquo;t make good first class
citizens in an object model. If you want to add richer behavior to a generated
class, the best way to do this is to wrap the generated protocol buffer class in
an application-specific class. Wrapping protocol buffers is also a good idea if
you don&rsquo;t have control over the design of the <code>.proto</code> file (if, say, you&rsquo;re
reusing one from another project). In that case, you can use the wrapper class
to craft an interface better suited to the unique environment of your
application: hiding some data and methods, exposing convenience functions, etc.
<strong>You should never add behavior to the generated classes by inheriting from
them</strong>. This will break internal mechanisms and is not good object-oriented
practice anyway.</div><h2 id=writing-a-message>Writing a Message</h2><p>Now let&rsquo;s try using your protocol buffer classes. The first thing you want your
address book application to be able to do is write personal details to your
address book file. To do this, you need to create and populate instances of your
protocol buffer classes and then write them to an output stream.</p><p>Here is a program which reads an <code>AddressBook</code> from a file, adds one new
<code>Person</code> to it based on user input, and writes the new <code>AddressBook</code> back out to
the file again. The parts which directly call or reference code generated by the
protocol compiler are highlighted.</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:#8f5902;font-style:italic>#!/usr/bin/env python3</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>import</span> <span style=color:#000>addressbook_pb2</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>import</span> <span style=color:#000>sys</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic># This function fills in a Person message based on user input.</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>def</span> <span style=color:#000>PromptForAddress</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>person</span><span style=color:#000;font-weight:700>):</span>
</span></span><span style=display:flex><span> <span style=color:#000>person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>id</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#204a87>int</span><span style=color:#000;font-weight:700>(</span><span style=color:#204a87>input</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>&#34;Enter person ID number: &#34;</span><span style=color:#000;font-weight:700>))</span>
</span></span><span style=display:flex><span> <span style=color:#000>person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>name</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#204a87>input</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>&#34;Enter name: &#34;</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#000>email</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#204a87>input</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>&#34;Enter email address (blank for none): &#34;</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>if</span> <span style=color:#000>email</span> <span style=color:#ce5c00;font-weight:700>!=</span> <span style=color:#4e9a06>&#34;&#34;</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#000>person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>email</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>email</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>while</span> <span style=color:#204a87;font-weight:700>True</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#000>number</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#204a87>input</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>&#34;Enter a phone number (or leave blank to finish): &#34;</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>if</span> <span style=color:#000>number</span> <span style=color:#ce5c00;font-weight:700>==</span> <span style=color:#4e9a06>&#34;&#34;</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>break</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#000>phone_number</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>phones</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>add</span><span style=color:#000;font-weight:700>()</span>
</span></span><span style=display:flex><span> <span style=color:#000>phone_number</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>number</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>number</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#000>phone_type</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#204a87>input</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>&#34;Is this a mobile, home, or work phone? &#34;</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>if</span> <span style=color:#000>phone_type</span> <span style=color:#ce5c00;font-weight:700>==</span> <span style=color:#4e9a06>&#34;mobile&#34;</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#000>phone_number</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>type</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>addressbook_pb2</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>Person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>PhoneType</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>PHONE_TYPE_MOBILE</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>elif</span> <span style=color:#000>phone_type</span> <span style=color:#ce5c00;font-weight:700>==</span> <span style=color:#4e9a06>&#34;home&#34;</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#000>phone_number</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>type</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>addressbook_pb2</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>Person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>PhoneType</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>PHONE_TYPE_HOME</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>elif</span> <span style=color:#000>phone_type</span> <span style=color:#ce5c00;font-weight:700>==</span> <span style=color:#4e9a06>&#34;work&#34;</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#000>phone_number</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>type</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>addressbook_pb2</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>Person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>PhoneType</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>PHONE_TYPE_WORK</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>else</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#204a87>print</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>&#34;Unknown phone type; leaving as default value.&#34;</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic># Main procedure: Reads the entire address book from a file,</span>
</span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic># adds one person based on user input, then writes it back out to the same</span>
</span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic># file.</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>if</span> <span style=color:#204a87>len</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>sys</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>argv</span><span style=color:#000;font-weight:700>)</span> <span style=color:#ce5c00;font-weight:700>!=</span> <span style=color:#0000cf;font-weight:700>2</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#204a87>print</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>&#34;Usage:&#34;</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>sys</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>argv</span><span style=color:#000;font-weight:700>[</span><span style=color:#0000cf;font-weight:700>0</span><span style=color:#000;font-weight:700>],</span> <span style=color:#4e9a06>&#34;ADDRESS_BOOK_FILE&#34;</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#000>sys</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>exit</span><span style=color:#000;font-weight:700>(</span><span style=color:#ce5c00;font-weight:700>-</span><span style=color:#0000cf;font-weight:700>1</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#000>address_book</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>addressbook_pb2</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>AddressBook</span><span style=color:#000;font-weight:700>()</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic># Read the existing address book.</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>try</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>with</span> <span style=color:#204a87>open</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>sys</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>argv</span><span style=color:#000;font-weight:700>[</span><span style=color:#0000cf;font-weight:700>1</span><span style=color:#000;font-weight:700>],</span> <span style=color:#4e9a06>&#34;rb&#34;</span><span style=color:#000;font-weight:700>)</span> <span style=color:#204a87;font-weight:700>as</span> <span style=color:#000>f</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#000>address_book</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>ParseFromString</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>f</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>read</span><span style=color:#000;font-weight:700>())</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>except</span> <span style=color:#c00;font-weight:700>IOError</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#204a87>print</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>sys</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>argv</span><span style=color:#000;font-weight:700>[</span><span style=color:#0000cf;font-weight:700>1</span><span style=color:#000;font-weight:700>]</span> <span style=color:#ce5c00;font-weight:700>+</span> <span style=color:#4e9a06>&#34;: Could not open file. Creating a new one.&#34;</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic># Add an address.</span>
</span></span><span style=display:flex><span><span style=color:#000>PromptForAddress</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>address_book</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>people</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>add</span><span style=color:#000;font-weight:700>())</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic># Write the new address book back to disk.</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>with</span> <span style=color:#204a87>open</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>sys</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>argv</span><span style=color:#000;font-weight:700>[</span><span style=color:#0000cf;font-weight:700>1</span><span style=color:#000;font-weight:700>],</span> <span style=color:#4e9a06>&#34;wb&#34;</span><span style=color:#000;font-weight:700>)</span> <span style=color:#204a87;font-weight:700>as</span> <span style=color:#000>f</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#000>f</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>write</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>address_book</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>SerializeToString</span><span style=color:#000;font-weight:700>())</span>
</span></span></code></pre></div><h2 id=reading-a-message>Reading a Message</h2><p>Of course, an address book wouldn&rsquo;t be much use if you couldn&rsquo;t get any
information out of it! This example reads the file created by the above example
and prints all the information in it.</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:#8f5902;font-style:italic>#!/usr/bin/env python3</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>import</span> <span style=color:#000>addressbook_pb2</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>import</span> <span style=color:#000>sys</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic># Iterates though all people in the AddressBook and prints info about them.</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>def</span> <span style=color:#000>ListPeople</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>address_book</span><span style=color:#000;font-weight:700>):</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>for</span> <span style=color:#000>person</span> <span style=color:#204a87;font-weight:700>in</span> <span style=color:#000>address_book</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>people</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#204a87>print</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>&#34;Person ID:&#34;</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>id</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#204a87>print</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>&#34; Name:&#34;</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>name</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>if</span> <span style=color:#000>person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>HasField</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>&#39;email&#39;</span><span style=color:#000;font-weight:700>):</span>
</span></span><span style=display:flex><span> <span style=color:#204a87>print</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>&#34; E-mail address:&#34;</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>email</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>for</span> <span style=color:#000>phone_number</span> <span style=color:#204a87;font-weight:700>in</span> <span style=color:#000>person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>phones</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>if</span> <span style=color:#000>phone_number</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>type</span> <span style=color:#ce5c00;font-weight:700>==</span> <span style=color:#000>addressbook_pb2</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>Person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>PhoneType</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>PHONE_TYPE_MOBILE</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#204a87>print</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>&#34; Mobile phone #: &#34;</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>end</span><span style=color:#ce5c00;font-weight:700>=</span><span style=color:#4e9a06>&#34;&#34;</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>elif</span> <span style=color:#000>phone_number</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>type</span> <span style=color:#ce5c00;font-weight:700>==</span> <span style=color:#000>addressbook_pb2</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>Person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>PhoneType</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>PHONE_TYPE_HOME</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#204a87>print</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>&#34; Home phone #: &#34;</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>end</span><span style=color:#ce5c00;font-weight:700>=</span><span style=color:#4e9a06>&#34;&#34;</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>elif</span> <span style=color:#000>phone_number</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>type</span> <span style=color:#ce5c00;font-weight:700>==</span> <span style=color:#000>addressbook_pb2</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>Person</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>PhoneType</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>PHONE_TYPE_WORK</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#204a87>print</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>&#34; Work phone #: &#34;</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>end</span><span style=color:#ce5c00;font-weight:700>=</span><span style=color:#4e9a06>&#34;&#34;</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#204a87>print</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>phone_number</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>number</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic># Main procedure: Reads the entire address book from a file and prints all</span>
</span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic># the information inside.</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>if</span> <span style=color:#204a87>len</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>sys</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>argv</span><span style=color:#000;font-weight:700>)</span> <span style=color:#ce5c00;font-weight:700>!=</span> <span style=color:#0000cf;font-weight:700>2</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#204a87>print</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>&#34;Usage:&#34;</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>sys</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>argv</span><span style=color:#000;font-weight:700>[</span><span style=color:#0000cf;font-weight:700>0</span><span style=color:#000;font-weight:700>],</span> <span style=color:#4e9a06>&#34;ADDRESS_BOOK_FILE&#34;</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#000>sys</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>exit</span><span style=color:#000;font-weight:700>(</span><span style=color:#ce5c00;font-weight:700>-</span><span style=color:#0000cf;font-weight:700>1</span><span style=color:#000;font-weight:700>)</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#000>address_book</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>addressbook_pb2</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>AddressBook</span><span style=color:#000;font-weight:700>()</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic># Read the existing address book.</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>with</span> <span style=color:#204a87>open</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>sys</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>argv</span><span style=color:#000;font-weight:700>[</span><span style=color:#0000cf;font-weight:700>1</span><span style=color:#000;font-weight:700>],</span> <span style=color:#4e9a06>&#34;rb&#34;</span><span style=color:#000;font-weight:700>)</span> <span style=color:#204a87;font-weight:700>as</span> <span style=color:#000>f</span><span style=color:#000;font-weight:700>:</span>
</span></span><span style=display:flex><span> <span style=color:#000>address_book</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>ParseFromString</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>f</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#000>read</span><span style=color:#000;font-weight:700>())</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#000>ListPeople</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>address_book</span><span style=color:#000;font-weight:700>)</span>
</span></span></code></pre></div><h2 id=extending-a-protobuf>Extending a Protocol Buffer</h2><p>Sooner or later after you release the code that uses your protocol buffer, you
will undoubtedly want to &ldquo;improve&rdquo; the protocol buffer&rsquo;s definition. If you want
your new buffers to be backwards-compatible, and your old buffers to be
forward-compatible &ndash; and you almost certainly do want this &ndash; then there are
some rules you need to follow. In the new version of the protocol buffer:</p><ul><li>you <em>must not</em> change the tag numbers of any existing fields.</li><li>you <em>must not</em> add or delete any required fields.</li><li>you <em>may</em> delete optional or repeated fields.</li><li>you <em>may</em> add new optional or repeated fields but you must use fresh tag
numbers (that is, tag numbers that were never used in this protocol buffer,
not even by deleted fields).</li></ul><p>(There are
<a href=/programming-guides/proto2#updating>some exceptions</a> to
these rules, but they are rarely used.)</p><p>If you follow these rules, old code will happily read new messages and simply
ignore any new fields. To the old code, optional fields that were deleted will
simply have their default value, and deleted repeated fields will be empty. New
code will also transparently read old messages. However, keep in mind that new
optional fields will not be present in old messages, so you will need to either
check explicitly whether they&rsquo;re set with <code>HasField('field_name')</code>, or provide a
reasonable default value in your <code>.proto</code> file with <code>[default = value]</code> after
the tag number. If the default value is not specified for an optional element, a
type-specific default value is used instead: for strings, the default value is
the empty string. For booleans, the default value is false. For numeric types,
the default value is zero. Note also that if you added a new repeated field,
your new code will not be able to tell whether it was left empty (by new code)
or never set at all (by old code) since there is no <code>HasField</code> check for it.</p><h2 id=advanced-usage>Advanced Usage</h2><p>Protocol buffers have uses that go beyond simple accessors and serialization. Be
sure to explore the
<a href=https://googleapis.dev/python/protobuf/latest/>Python API reference</a> to see
what else you can do with them.</p><p>One key feature provided by protocol message classes is <em>reflection</em>. You can
iterate over the fields of a message and manipulate their values without writing
your code against any specific message type. One very useful way to use
reflection is for converting protocol messages to and from other encodings, such
as XML or JSON (see <a href=#parsing-serialization>Parsing and Serialization</a> for an
example). A more advanced use of reflection might be to find differences between
two messages of the same type, or to develop a sort of &ldquo;regular expressions for
protocol messages&rdquo; in which you can write expressions that match certain message
contents. If you use your imagination, it&rsquo;s possible to apply Protocol Buffers
to a much wider range of problems than you might initially expect!</p><p>Reflection is provided as part of the
<a href=https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message><code>Message</code> interface</a>.</p></div></main></div></div><footer class="bg-dark py-5 row d-print-none"><div class="container-fluid mx-sm-5"><div class=row><div class="col-6 col-sm-4 text-xs-center order-sm-2"><ul class="list-inline mb-0"><li class="list-inline-item mx-2 h3" data-toggle=tooltip data-placement=top title="Stack Overflow" aria-label="Stack Overflow"><a class=text-white target=_blank rel=noopener href=https://stackoverflow.com/questions/tagged/protocol-buffers aria-label="Stack Overflow"><i class="fab fa-stack-overflow"></i></a></li></ul><script type=text/javascript id=cookiebanner src=https://cdn.jsdelivr.net/gh/dobarkod/cookie-banner@1.2.2/dist/cookiebanner.min.js data-height=50px data-message="Protobuf.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic." data-bg=#ffb data-fg=#000 data-position=bottom data-padding="10px 16px" data-close-text="OK, got it" data-font-size=18px data-moreinfo=https://policies.google.com/technologies/cookies></script></div><div class="col-6 col-sm-4 text-right text-xs-center order-sm-3"><ul class="list-inline mb-0"><li class="list-inline-item mx-2 h3" data-toggle=tooltip data-placement=top title=GitHub aria-label=GitHub><a class=text-white target=_blank rel=noopener href=https://github.com/protocolbuffers/protobuf aria-label=GitHub><i class="fab fa-github"></i></a></li><li class="list-inline-item mx-2 h3" data-toggle=tooltip data-placement=top title="Developer mailing list" aria-label="Developer mailing list"><a class=text-white target=_blank rel=noopener href=https://groups.google.com/g/protobuf aria-label="Developer mailing list"><i class="fa fa-envelope"></i></a></li></ul><script type=text/javascript id=cookiebanner src=https://cdn.jsdelivr.net/gh/dobarkod/cookie-banner@1.2.2/dist/cookiebanner.min.js data-height=50px data-message="Protobuf.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic." data-bg=#ffb data-fg=#000 data-position=bottom data-padding="10px 16px" data-close-text="OK, got it" data-font-size=18px data-moreinfo=https://policies.google.com/technologies/cookies></script></div><div class="col-12 col-sm-4 text-center py-2 order-sm-2"><small class=text-white>&copy; 2026 Google LLC All Rights Reserved</small>
<small class=ml-1><a href=https://policies.google.com/privacy target=_blank rel=noopener>Privacy Policy</a></small>
<span class=text-white>Hosted by GitHub Pages.</span> <a href=https://docs.github.com/en/site-policy/privacy-policies/github-privacy-statement target=_blank>GitHub Privacy Statement</a></div></div></div></footer></div><script src=/js/main.min.c91cdfdcc1576ecc360abc6f1c3ca0485d047f65ac6d3203ec57ed29e0af808b.js integrity="sha256-yRzf3MFXbsw2CrxvHDygSF0Ef2WsbTID7FftKeCvgIs=" crossorigin=anonymous></script><script defer src=/js/click-to-copy.min.73478a7d4807698aed7e355eb23f9890ca18fea3158604c8471746d046702bad.js integrity="sha256-c0eKfUgHaYrtfjVesj+YkMoY/qMVhgTIRxdG0EZwK60=" crossorigin=anonymous></script><script src=/js/tabpane-persist.js></script></body></html>