[ s e | c t | i o | n s ]
Featured Content Ads
add advertising herePython equipment providing versatile tree records constructions for organizing lists and dicts into sections.
Sections is designed to be:
Featured Content Ads
add advertising here- Intuitive: Start speedy, verbalize much less time studying the docs.
- Scalable: Develop arbitrarily advanced bushes as your bid scales.
- Flexible: Impulsively safe nodes with customized attributes, properties, and techniques on the hover.
- Instant: Made with performance in solutions – safe admission to lists and sub-lists/dicts in Θ(1) time in many cases. Undercover agent the Efficiency section for the fat shrimp print.
- Legitimate: Contains an exhaustive check suite and 100% code protection.
Links
Usage
import sections menu = sections( 'Breakfast', 'Dinner', well-known=['Bacon&Eggs', 'Burger'], aspect=['HashBrown', 'Fries'], )
$ print(menu) _________________________ │ _____________________ │ │ │ 'Breakfast' │ │ │ │ well-known='1st baron beaverbrook&Eggs' │ │ │ │ aspect='HashBrown' │ │ │ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ │ │ _________________ │ │ │ 'Dinner' │ │ │ │ well-known='Burger' │ │ │ │ aspect='Fries' │ │ │ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ │ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Featured Content Ads
add advertising here# menu's API with the anticipated results: train menu.mains == ['Bacon&Eggs', 'Burger'] train menu.aspects == ['HashBrown', 'Fries'] train menu['Breakfast'].well-known == '1st baron beaverbrook&Eggs' train menu['Breakfast'].aspect == 'HashBrown' train menu['Dinner'].well-known == 'Burger' train menu['Dinner'].aspect == 'Fries' train menu('aspects', checklist) == ['HashBrown', 'Fries'] train menu('aspects', dict) == {'Breakfast': 'HashBrown', 'Dinner': 'Fries'} # root section/node: train isinstance(menu, sections.Half) # shrimp one sections/nodes: train isinstance(menu['Breakfast'], sections.Half) train isinstance(menu['Dinner'], sections.Half)
Scale in dimension:
library = sections( "My Bookshelf", sections({'Fiction'}, 'LOTR', 'Harry Potter', author=['JRR Tolkien', 'JK Rowling'], topic=[{'Fantasy'}, 'Hobbits', 'Wizards'],), sections({'Non-Fiction'}, 'Frequent Relativity', 'A Brief History of Time', author=['Albert Einstein', 'Steven Hawking'], topic=[{'Physics'}, 'Time, Gravity', 'Black Holes'], ), )
$ print(library) ________________________________________ │ 'My Bookshelf' │ │ ______________________________ │ │ │ 'Fiction' │ │ │ │ topic='Delusion' │ │ │ │ ________________________ │ │ │ │ │ 'LOTR' │ │ │ │ │ │ author='JRR Tolkien' │ │ │ │ │ │ topic ='Hobbits' │ │ │ │ │ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ │ │ │ │ _______________________ │ │ │ │ │ 'Harry Potter' │ │ │ │ │ │ author='JK Rowling' │ │ │ │ │ │ topic ='Wizards' │ │ │ │ │ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ │ │ │ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ │ │ __________________________________ │ │ │ 'Non-Fiction' │ │ │ │ topic='Physics' │ │ │ │ ____________________________ │ │ │ │ │ 'Frequent Relativity' │ │ │ │ │ │ author='Albert Einstein' │ │ │ │ │ │ topic ='Time, Gravity' │ │ │ │ │ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ │ │ │ │ ___________________________ │ │ │ │ │ 'A Brief History of Time' │ │ │ │ │ │ author='Steven Hawking' │ │ │ │ │ │ topic ='Murky Holes' │ │ │ │ │ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ │ │ │ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ │ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Attrs: Plural/singular hybrid attributes and more
Utilize much less time deciding between the usage of the singular or plural invent for an attribute name:
responsibilities = sections('pay bill', 'tremendous', station=['completed', 'started']) train responsibilities.statuses == ['completed', 'started'] train responsibilities['pay bill'].station == 'done' train responsibilities['clean'].station == 'started'
Whenever you don’t like this characteristic, merely turn it off as shown within the Particulars – Plural/singular attributes section.
Properties: Without considerations add on the hover
Properties and techniques are mechanically added to all nodes in a structure returned from a sections()
call when handed as key phrase arguments:
time table = sections( 'Weekdays', 'Weekend', hours_per_day=[[8, 8, 6, 10, 8], [4, 6]], hours=property(lambda self: sum(self.hours_per_day)), ) train time table['Weekdays'].hours == 40 train time table['Weekend'].hours == 10 train time table.hours == 50
Along side properties and techniques this model doesn’t impact the class definitions of Sections/nodes from varied constructions. Undercover agent the Particulars – Properties/techniques section for the scheme in which this works.
Construction: Make gradually or all straight away
Make section-by-section, section-wise, attribute-wise, or varied ways:
def demo_different_construction_techniques(): """Instance enhance ways for producing the identical structure.""" # Building section-by-section books = sections() books['LOTR'] = sections(topic='Hobbits', author='JRR Tolkien') books['Harry Potter'] = sections(topic='Wizards', author='JK Rowling') demo_resulting_object_api(books) # Half-wise enhance books = sections( sections('LOTR', topic='Hobbits', author='JRR Tolkien'), sections('Harry Potter', topic='Wizards', author='JK Rowling') ) demo_resulting_object_api(books) # Attribute-wise enhance books = sections( 'LOTR', 'Harry Potter', issues=['Hobbits', 'Wizards'], authors=['JRR Tolkien', 'JK Rowling'] ) demo_resulting_object_api(books) # setattr put up-enhance books = sections( 'LOTR', 'Harry Potter', ) books.issues = ['Hobbits', 'Wizards'] books['LOTR'].author = 'JRR Tolkien' books['Harry Potter'].author = 'JK Rowling' demo_resulting_object_api(books) def demo_resulting_object_api(books): """Instance Half structure API and anticipated results.""" train books.names == ['LOTR', 'Harry Potter'] train books.issues == ['Hobbits', 'Wizards'] train books.authors == ['JRR Tolkien', 'JK Rowling'] train books['LOTR'].topic == 'Hobbits' train books['LOTR'].author == 'JRR Tolkien' train books['Harry Potter'].topic == 'Wizards' train books['Harry Potter'].author == 'JK Rowling' demo_different_construction_techniques()
Particulars
Half names
The non-key phrase arguments handed exact into a sections()
call interpret the section names and are accessed thru the attribute name
. The names are weak like keys
in a dict
to safe admission to every shrimp one section of the basis section node:
books = sections( 'LOTR', 'Harry Potter', topic=['Hobbits', 'Wizards'], author=['JRR Tolkien', 'JK Rowling'] ) train books.names == ['LOTR', 'Harry Potter'] train books['LOTR'].name == 'LOTR' train books['Harry Potter'].name == 'Harry Potter'
Names are optional, and by default, younger of us names are assigned as integer values equivalent to indices in an array, while a root has a default keyvalue of sections.SectionNone
:
sect = sections(x=['a', 'b']) train sect.sections.names == [0, 1] train sect.name is sections.SectionNone # the string representation of sections.SectionNone is 'section': train str(sect.name) == 'sections'
Mum or dad names and attributes
A parent section name can optionally be offered as the indispensable argument in a sections()
call by defining it in a dilemma (surrounding it with curly brackets). This technique avoids an further level of braces when instantiating Half objects. This belief applies also for outlining parent attributes:
library = sections( {"My Bookshelf"}, [{'Fantasy'}, 'LOTR', 'Harry Potter'], [{'Academic'}, 'Advanced Mathematics', 'Physics for Engineers'], topic=[{'All my books'}, [{'Imaginary things'}, 'Hobbits', 'Wizards'], [{'School'}, 'Numbers', 'Forces']], ) train library.name == "My Bookshelf" train library.sections.names == ['Fantasy', 'Academic'] train library['Fantasy'].sections.names == ['LOTR', 'Harry Potter'] train library['Academic'].sections.names == [ 'Advanced Mathematics', 'Physics for Engineers' ] train library['Fantasy']['Harry Potter'].name == 'Harry Potter' train library.topic == 'All my books' train library['Fantasy'].topic == 'Imaginary issues' train library['Academic'].topic == 'College'
Return attributes as a checklist, dict, or iterable
Procure entry to the records in varied kinds with the gettype
argument in Half.__call__() as follows:
menu = sections('Breakfast', 'Dinner', aspects=['HashBrown', 'Fries']) # return as checklist always, despite the real fact that a single part is returned train menu('aspects', checklist) == ['HashBrown', 'Fries'] train menu['Breakfast']('aspect', checklist) == ['HashBrown'] # return as dict train menu('aspects', dict) == {'Breakfast': 'HashBrown', 'Dinner': 'Fries'} train menu['Breakfast']('aspect', dict) == {'Breakfast': 'HashBrown'} # return as iterator over aspects in checklist (quickest scheme, theoretically) for i, value in enumerate(menu('aspects', iter)): train value == ['HashBrown', 'Fries'][i] for i, value in enumerate(menu['Breakfast']('aspect', iter)): train value == ['HashBrown'][i]
Undercover agent the Half.__call__() scheme within the References section of the docs for more alternatives.
Location the default return kind when having access to structure attributes by changing Half.default_gettype
as follows:
menu = sections('Breakfast', 'Dinner', aspects=['HashBrown', 'Fries']) menu['Breakfast'].default_gettype = dict # dilemma for ultimate 'Breakfast' node train menu.aspects == ['HashBrown', 'Fries'] train menu['Breakfast']('aspect') == {'Breakfast': 'HashBrown'} menu.cls.default_gettype = dict # dilemma for all nodes in `menu` train menu('aspects') == {'Breakfast': 'HashBrown', 'Dinner': 'Fries'} train menu['Breakfast']('aspect') == {'Breakfast': 'HashBrown'} sections.Half.default_gettype = dict # dilemma for all constructions tasks1 = sections('pay bill', 'tremendous', station=['completed', 'started']) tasks2 = sections('pay bill', 'tremendous', station=['completed', 'started']) train tasks1('statuses') == {'pay bill': 'done', 'tremendous': 'started'} train tasks2('statuses') == {'pay bill': 'done', 'tremendous': 'started'}
The above will also work for having access to attributes within the invent object.attr
nonetheless ultimate if the node doesn’t beget the attribute attr
, otherwise this would possibly per chance return the non-iterable raw value for attr
. Because of this truth, for consistency, safe admission to attributes the usage of Half.__call__() like above if you happen to would prefer to always receive an iterable invent of the attributes.
Plural/singular attributes
When an attribute is now not stumbled on in a Half node, every the plural and singular
kinds of the observe are then checked to gaze if the node consists of the attribute
beneath those kinds of the observe. In the occasion that they are mild now not stumbled on, the node will
recursively repeat the identical search on every of its younger of us, concatenating the
results exact into a checklist or dict. The marvelous attribute name in every node supplied a
corresponding value is with out reference to name became once given within the predominant phrase argument’s key
(i.e. station
within the instance beneath).
Whenever you don’t like this characteristic, merely turn it off the usage of the following:
import pytest responsibilities = sections('pay bill', 'tremendous', station=['completed', 'started']) train responsibilities.statuses == ['completed', 'started'] # turn off for all future constructions: sections.Half.use_pluralsingular = Fraudulent responsibilities = sections('pay bill', 'tremendous', station=['completed', 'started']) with pytest.raises(AttributeError): responsibilities.statuses # this now raises an AttributeError
Display, nonetheless, that this must mild traverse descendant nodes to gaze within the occasion that they
beget the requested attribute. To stop the usage of this characteristic also, safe admission to
attributes the usage of the Half.get_node_attr() scheme as a replacement.
Properties/techniques
Each and every sections()
call returns a structure containing nodes of a varied class created in a class factory feature, where the unfamiliar class definition consists of no logic other than that it inherits from the Half class. This enables properties/techniques added to 1 structure’s class definition to now not impact the class definitions of nodes from varied constructions.
Subclassing
Inheriting Half is easy, the ultimate requirement is to call colossal().__init__kwds)
at some level in __init__()
like beneath if you happen to override that scheme:
class Library(sections.Half): """My library class.""" def __init__(self, stamp="Personalized default value", kwds): """Bolt kwds to colossal.""" colossal().__init__(kwds) self.stamp = stamp @property def genres(self): """A synonym for sections.""" if self.isroot: return self.sections else: lift AttributeError('This library has ultimate 1 level of genres') @property def books(self): """A synonym for leaves.""" return self.lea