title: How does Python provide a maintainable way to pass data structures around in a system?
body: <p>I am new to dynamic languages in general, and I have discovered that languages like Python prefer simple data structures, like dictionaries, for sending data between parts of a system (across functions, modules, etc).</p>
  
  <p>In the C# world, when two parts of a system communicate, the developer defines a class (possibly one that implements an interface) that contains properties (like a Person class with a Name, Birth date, etc) where the sender in the system instantiates the class and assigns values to the properties.  The receiver then accesses these properties.  The class is called a DTO and it is "well- defined" and <strong>explicit</strong>.  If I remove a property from the DTO's class, the compiler will instantly warn me of all parts of the code that use that DTO and are attempting to access what is now a non-existent property.  I know exactly what has broken in my codebase.</p>
  
  <p>In Python, functions that produce data (senders) create <strong>implicit</strong> DTOs by building up dictionaries and returning them.  Coming from a compiled world, this scares me.  I immediately think of the scenario of a large code base where a function producing a dictionary has the name of a key changed (or a key is removed altogether) and boom- tons of potential KeyErrors begin to crop up as pieces of the code base that work with that dictionary and expect a key are no longer able to access the data they were expecting.  Without unit testing, the developer would have no reliable way of knowing where these errors will appear.</p>
  
  <p>Maybe I misunderstand altogether.  Are dictionaries a best practice tool for passing data around?  If so, how do developers solve this kind of problem?  How are implicit data structures and the functions that use them maintained?  How do I become less afraid of what seems like a huge amount of uncertainty?</p>