| <!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&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’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’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’re going to use is a very simple “address book” application that |
| can read and write people’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’s built into the |
| language, but it doesn’t deal well with schema evolution, and also doesn’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 – such as encoding 4 ints as “12:3:-23:67”. 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 “examples” |
| 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’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>"2023"</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’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 – 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 – 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 – |
| 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 “tag” 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’ll find a complete guide to writing <code>.proto</code> files – including all the |
| possible field types – in the |
| <a href=/programming-guides/editions>Protocol Buffer Language Guide</a>. |
| Don’t go looking for facilities similar to class inheritance, though – protocol |
| buffers don’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’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’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’s source code lives – the current directory is used if you |
| don’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…:</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 – |
| 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’t generate your data access code for you directly. Instead |
| (as you’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>''</span><span style=color:#000;font-weight:700>,</span> |
| </span></span><span style=display:flex><span> <span style=color:#4e9a06>'main.proto'</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>'</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>\"\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>\"</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\"</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'</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>'google3.main_pb2'</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>'_PERSON'</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>'_PERSON'</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>'_PERSON_PHONENUMBER'</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>'_PERSON_PHONENUMBER'</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>'_PERSON_PHONETYPE'</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>'_PERSON_PHONETYPE'</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>'_ADDRESSBOOK'</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>'_ADDRESSBOOK'</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>"John Doe"</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>"jdoe@example.com"</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>"555-4321"</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’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>"1234"</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’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>"John Doe"</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>"jdoe@example.com"</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’t provide additional functionality; they don’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’t have control over the design of the <code>.proto</code> file (if, say, you’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’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>"Enter person ID number: "</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>"Enter name: "</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>"Enter email address (blank for none): "</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>""</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>"Enter a phone number (or leave blank to finish): "</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>""</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>"Is this a mobile, home, or work phone? "</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>"mobile"</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>"home"</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>"work"</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>"Unknown phone type; leaving as default value."</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>"Usage:"</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>"ADDRESS_BOOK_FILE"</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>"rb"</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>": Could not open file. Creating a new one."</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>"wb"</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’t be much use if you couldn’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>"Person ID:"</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>" Name:"</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>'email'</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>" E-mail address:"</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>" Mobile phone #: "</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>""</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>" Home phone #: "</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>""</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>" Work phone #: "</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>""</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>"Usage:"</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>"ADDRESS_BOOK_FILE"</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>"rb"</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 “improve” the protocol buffer’s definition. If you want |
| your new buffers to be backwards-compatible, and your old buffers to be |
| forward-compatible – and you almost certainly do want this – 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’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 “regular expressions for |
| protocol messages” in which you can write expressions that match certain message |
| contents. If you use your imagination, it’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>© 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> |