19.1 converting the dynamic properties of data.
First, go to a website to download oreilly standard json data.
Import the urlopen the urllib.request from Import Represents warnings Import OS Import JSON # Import the pprint the URL = 'http://www.oreilly.com/pub/sc/osconfeed' the JSON = 'Data / osconfeed.json' DEF Load (): # Search if the file exists, to download does not exist. Not os.path.exists IF (the JSON): MSG = 'Downloading {{}} to' the format (the URL, the JSON). warnings.warn (MSG) # with the use of two context managers, respectively, for reading read take and save the file with urlopen (the URL of) AS Remote, Open (JSON, 'wb') AS local: local.write (remote.read ()) with Open (JSON) AS fp: return the json.load (fp) IF __name__ == '__main__': Print (Load ()) # pprint.pprint (Load ())
A series of the data read operation in accordance with some embodiments of the book.
In [20]: feed = load() In [21]: sorted(feed['Schedule'].keys()) Out[21]: ['conferences', 'events', 'speakers', 'venues'] In [22]: for key, value in sorted(feed['Schedule'].items()): ...: print('{:3} {}'.format(len(value), key)) ...: 1 conferences 494 events 357 speakers 53 venues In [23]: feed['Schedule']['speakers'][-1]['name'] Out[23]: 'Carina C. Zone ' In [24]:
This reading, from what I understand to set Dictionary Dictionary set list last set of dictionaries.
Json data access using dynamic properties.
Like a book written by a particular class, a. Way to read data, the data is read by reading the object attributes method.
The main use of __getattr__ implementation.
Import abc the Collections from from osconfeed Import the Load class FrozenJSON: DEF __init __ (Self, Mapping): # create a copy of the dictionary, shallow copy Self .__ dict the Data = (Mapping) # When the object does not have this property when invoked. __getattr __ DEF (Self, name): # Search __data whether the object properties have attributes that have a direct return IF hasattr (Self .__ the Data, name): return getattr (Self .__ the Data, name) the else: # attempt to read the name of the index value, and call the class method. the try: return FrozenJSON.build (Self .__ Data [name]) the except a KeyError AS E: The raise AttributeError (* e.args) from E @classmethod # calling a class method determines the parameters DEF Build (CLS, obj): '' ' the JSON format data is set to a standard dictionary with a list of the type ' '' # FrozenJSON instance if the return type is mapped IF the isinstance (obj, abc.Mapping): return CLS (obj) # If the list, each element recursively passed Build elif the isinstance (obj, abc.MutableSequence): return [cls.build (Item) for obj in Item] # otherwise return the data the else: return obj IF the __name__ == ' __main__ ': L = Load () Feed = FrozenJSON (L) Print (feed.Schedul)
This is done according to the method of their book, interpreted code, or data in addition to the final list to return data (has been processed), the other case, the objects are returned FrozenJSON. A series of operations in accordance with the requirements of the book.
In [8]: from osconfeed import load In [9]: from explore0 import FrozenJSON In [10]: raw_feed = load() In [11]: feed = FrozenJSON(raw_feed) In [12]: len(feed.Schedule.speakers) Out[12]: 357 In [13]: for key, value in sorted(feed.Schedule.items()): ...: print('{:3} {}'.format(len(value), key)) ...: 1 conferences 494 events 357 speakers 53 venues In [14]: feed.Schedule.speakers[-1].name Out[14]: 'Carina C. Zona' In [15]: talk = feed.Schedule.events[40] In [16]: type(talk) Out[16]: explore0.FrozenJSON In [17]: talk.name Out[17]: 'There *Will* Be Bugs' In [18]: talk.speakers Out[18]: [3471, 5199] In [19]: talk.flavor --------------------------------------------------------------------------- KeyError Traceback (most recent call last) ~/study/Fluent_Python/第19章/explore0.py in __getattr__(self, name) 18 try: ---> 19 return FrozenJSON.build(self.__data[name]) 20 except KeyError as e: KeyError: 'flavor' The above exception was the direct cause of the following exception: AttributeError Traceback (most recent call last) <ipython-input-19-abf3275fce15> in <module> ----> 1 talk.flavor ~/study/Fluent_Python/第19章/explore0.py in __getattr__(self, name) 19 return FrozenJSON.build(self.__data[name]) 20 except KeyError as e: ---> 21 raise AttributeError(*e.args) from e 22 23 @classmethod AttributeError: flavor In [20]: talk.keys() Out[20]: dict_keys(['serial', 'name', 'event_type', 'time_start', 'time_stop', 'venue_serial', 'description', 'website_url', 'speakers', 'categories']) In [21]: talk.items() Out[21]: dict_items([('serial', 33950), ('name', 'There *Will* Be Bugs'), ('event_type', '40-minute conference session'), ('time_start', '2014-07-23 14:30:00'), ('time_stop', '2014-07-23 15:10:00'), ('venue_serial', 1449), ('description', 'If you're pushing the envelope of programming (or of your own skills)... and even when you’re not... there *will* be bugs in your code. Don't panic! We cover the attitudes and skills (not taught in most schools) to minimize your bugs, track them, find them, fix them, ensure they never recur, and deploy fixes to your users.\r\n'), ('website_url', 'https://conferences.oreilly.com/oscon/oscon2014/public/schedule/detail/33950'), ('speakers', [3471, 5199]), ('categories', ['Python'])]) In [22]:
After repackaging the object, property method itself can be used, when the data type is non-return JSON data included, return data.
Because if hasattr (self .__ data, name): there is return getattr (self .__ data, name), you can call the original method own dictionary type easily.
Handles invalid attribute name
Written in front of the class, there is no special treatment for the name attribute Python keywords.
In [22]: grad = FrozenJSON({'name':'Jim Bo','class':1982}) In [23]: grad.name Out[23]: 'Jim Bo' In [24]: grad.class File "<ipython-input-24-bb5c99ef29c5>", line 1 grad.class ^ SyntaxError: invalid syntax
Getattr method attributes can be read.
In [25]: getattr(grad, 'class') Out[25]: 1982
Of course, you can at the time of the initialization data, find out if there is a key attribute, or other undesirable properties.
Collections ABC Import from Import keyword from osconfeed Import Load class FrozenJSON: DEF the __init __ (Self, Mapping): Self .__ Data} = { # scan all the keys, the keyword is found, add a _ for Key, in mapping.items value ( ): iF keyword.iskeyword (Key): Key + = '_' Self .__ Data [Key] = value # when the attribute is not the object when invoked. DEF __getattr __ (Self, name): # Print (name) # lookup object properties __data if there are so property, there is a direct return mainly dictionaries province of some properties. IF hasattr (Self .__ the Data, name): return getattr (Self. the __DATA, name) the else: # attempt to read the name of the index value, and call the class method. the try: return FrozenJSON.build (Self .__ Data [name]) the except a KeyError AS E: The raise AttributeError (* e.args) from E @classmethod # class method calls the parameters determined DEF Build (CLS, obj): '' ' JSON format data is set to a standard dictionary with a list of the type '' ' # FrozenJSON instance if the return type is mapped IF the isinstance (obj, abc.Mapping): return CLS (obj) # If the list, each element recursively passed Build elif the isinstance (obj, abc.MutableSequence): return [cls.build (Item) for obj in Item] # otherwise return the data the else: return obj IF the __name__ == '__main__': l = load() feed = FrozenJSON(l) print(feed.Schedul)
In [26]: from explore1 import FrozenJSON In [27]: grad = FrozenJSON({'name':'Jim Bo','class':1982}) In [28]: grad.class_ Out[28]: 1982
Some naming Python does not meet the standard can not be used to acquire property, such as:
In [29]: x = FrozenJSON({'2be': 'or not'}) In [30]: x.2be File "<ipython-input-30-8694215ab5bd>", line 1 x.2be ^ SyntaxError: invalid syntax
Can () method to determine whether the name is correct Python variable names, if it does not meet or can be modified directly through an error s.isidentifier.
In a flexible way to create objects using __new__ way.
This section let me __new__ have a more full understanding, learn to create objects when one of the variable length parameter which is to prepare examples of parametric
__new__ allowed to return to an example, instance will be returned as the first argument (self) passed __init__ method.
Because when you call the __init__ method to pass instance, and still return any value, all __init__ method is actually "illegal initialize"
And examples of instances __new___ returned if not class, the interpreter does not call the __init__ method.
T_new class: # real process of constructing a class, wherein the parameter may be acquired. __ __new DEF (CLS, args *, ** kwargs): Print (f'this __new__ is args => {!} R & lt args, kwargs => {!} R & lt kwargs') count_args = len (args) IF count_args <2: Print (args, kwargs) return 'a' the else: return Super () .__ new new __ (CLS) # where only instances of the class, for instance attributes, if examples are not examples of the class, not initialized def __init __ (self, * attr ): Print ( 'My attr IS', attr) self.attr attr = DEF __repr __ (Self): IF the hasattr (Self, 'attr'): return STR (self.attr) the else: return Self if __name__ == '__main__': t = T_New('xb',) print(t) t1 = T_New('xb1','xb2') print(t1)
/usr/local/bin/python3.7 /Users/shijianzhong/study/Fluent_Python/第19章/t.py this __new__ args =>('xb',), kwargs =>{} ('xb',) {} a this __new__ args =>('xb1', 'xb2'), kwargs =>{} my attr is ('xb1', 'xb2') ('xb1', 'xb2')
This is my own to write test code.
The following method of the above class book substituted method according to the wording of __new__.
Import abc the Collections from from osconfeed Import the Load class FrozenJSON: DEF __new __ (CLS, obj): # judge the incoming objects, if the map type, create an instance of the normal IF isinstance (obj, abc.Mapping): return Super () .__ new new __ ( CLS) # recursive call if the new instance list elif the isinstance (obj, abc.MutableSequence): return [CLS (Item) for obj in Item] # If the other input value returns the else: return obj DEF the __init __ (Self, Mapping): Self Mapping Data = .__ DEF __getattr __ (Self, name): IF the hasattr (Self .__ Data, name): return getattr (Self .__ Data, name) the else: the try: # attempt instance of the data, to test the data. FrozenJSON return (Self .__ Data [name]) the except a KeyError AS E: The raise AttributeError (* e.args) from E IF the __name__ == '__main__': L = Load () Feed = FrozenJSON (L) # Print (feed.Schedule .speakers [-1] .name)
Consider a very powerful way to avoid writing a class method, the direct incoming call type judgment __new__ examples of output by reading different data objects.