J'ai une classe nommée Tuple en python
class Town(collections.namedtuple('Town', [
'name',
'population',
'coordinates',
'population',
'capital',
'state_bird'])):
# ...
J'aimerais convertir les instances de la ville en dictionnaires. Je ne veux pas que cela soit lié rigidement aux noms ou au nombre de champs dans une ville.
Y a-t-il un moyen de l'écrire de sorte que je puisse ajouter plus de champs ou passer un nom totalement différent, Tuple, et obtenir un dictionnaire.
Je ne peux pas modifier la définition de classe d'origine comme dans le code de quelqu'un d'autre. Donc, je dois prendre une instance d'une ville et la convertir en dictionnaire.
TL; DR: il existe une méthode _asdict
fournie pour cela.
Voici une démonstration de l'utilisation:
>>> fields = ['name', 'population', 'coordinates', 'capital', 'state_bird']
>>> Town = collections.namedtuple('Town', fields)
>>> funkytown = Town('funky', 300, 'somewhere', 'lipps', 'chicken')
>>> funkytown._asdict()
OrderedDict([('name', 'funky'),
('population', 300),
('coordinates', 'somewhere'),
('capital', 'lipps'),
('state_bird', 'chicken')])
Ceci est un méthode documentée de namedtuples, c'est-à-dire contrairement à la convention habituelle dans python le trait de soulignement principal du nom de la méthode n'est pas là pour décourager. utiliser . Avec les autres méthodes ajoutées aux namedtuples, _make
, _replace
, _source
, _fields
, il contient le trait de soulignement uniquement pour tenter d'éviter les conflits avec les noms de champs possibles.
Remarque: Pour du code 2.7.5 <python version <3.5.0 à l'état sauvage, vous pouvez voir cette version:
>>> vars(funkytown)
OrderedDict([('name', 'funky'),
('population', 300),
('coordinates', 'somewhere'),
('capital', 'lipps'),
('state_bird', 'chicken')])
Pendant un certain temps, la documentation avait mentionné que _asdict
était obsolète (voir here ) et avait suggéré d'utiliser la méthode intégrée vars . Ce conseil est maintenant obsolète; afin de corriger n bogue lié au sous-classement, la propriété __dict__
qui était présente sur namedtuples a de nouveau été supprimée par this commit .
Il existe une méthode intégrée sur namedtuple
instances pour cela, _asdict
.
Comme indiqué dans les commentaires, sur certaines versions, vars()
le fera également, mais il dépend apparemment beaucoup des détails de la construction, alors que __asdict
_ devrait être fiable. Dans certaines versions, __asdict
_ était marqué comme obsolète, mais les commentaires indiquent que ce n'est plus le cas depuis 3.4.
Sous Ubuntu 14.04 Les versions LTS de python2.7 et python3.4, la propriété __dict__
fonctionnait comme prévu. La méthode _asdict
a également fonctionné, mais je suis enclin à utiliser l'api de propriété uniforme et uniforme, défini par des normes, au lieu du paramètre non localisé localisé. uniforme api.
$ python2.7
# Works on:
# Python 2.7.6 (default, Jun 22 2015, 17:58:13) [GCC 4.8.2] on linux2
# Python 3.4.3 (default, Oct 14 2015, 20:28:29) [GCC 4.8.4] on linux
import collections
Color = collections.namedtuple('Color', ['r', 'g', 'b'])
red = Color(r=256, g=0, b=0)
# Access the namedtuple as a dict
print(red.__dict__['r']) # 256
# Drop the namedtuple only keeping the dict
red = red.__dict__
print(red['r']) #256
Voir dict est la manière sémantique d’obtenir un dictionnaire représentant quelque chose (du moins à ma connaissance).
Il serait bien d’accumuler une table avec les principales versions python, leurs plates-formes et leur prise en charge de __dict__
, je n’ai actuellement qu’une version de plate-forme et deux versions python .
| Platform | PyVer | __dict__ | _asdict |
| -------------------------- | --------- | -------- | ------- |
| Ubuntu 14.04 LTS | Python2.7 | yes | yes |
| Ubuntu 14.04 LTS | Python3.4 | yes | yes |
| CentOS Linux release 7.4.1708 | Python2.7 | no | yes |
| CentOS Linux release 7.4.1708 | Python3.4 | no | yes |
| CentOS Linux release 7.4.1708 | Python3.6 | no | yes |
Cas n ° 1: un tuple à une dimension
Tuple_ROLES = (
(912,"Role 21"),
(913,"Role 22"),
(925,"Role 23"),
(918,"Role 24"),
)
Tuple_ROLES[912] #==> Error because it is out of bounce.
Tuple_ROLES[ 2] #==> will show Role 23.
DICT1_ROLE = {k:v for k, v in Tuple_ROLES }
DICT1_ROLE[925] # will display "Role 23"
Cas n ° 2: Tuple à deux dimensions
Exemple: DICT_ROLES [961] # affichera 'Programmeur back-end'
NAMEDTUPLE_ROLES = (
('Company', (
( 111, 'Owner/CEO/President'),
( 113, 'Manager'),
( 115, 'Receptionist'),
( 117, 'Marketer'),
( 119, 'Sales Person'),
( 121, 'Accountant'),
( 123, 'Director'),
( 125, 'Vice President'),
( 127, 'HR Specialist'),
( 141, 'System Operator'),
)),
('Restaurant', (
( 211, 'Chef'),
( 212, 'Waiter/Waitress'),
)),
('Oil Collector', (
( 211, 'Truck Driver'),
( 213, 'Tank Installer'),
( 217, 'Welder'),
( 218, 'In-house Handler'),
( 219, 'Dispatcher'),
)),
('Information Technology', (
( 912, 'Server Administrator'),
( 914, 'Graphic Designer'),
( 916, 'Project Manager'),
( 918, 'Consultant'),
( 921, 'Business Logic Analyzer'),
( 923, 'Data Model Designer'),
( 951, 'Programmer'),
( 953, 'WEB Front-End Programmer'),
( 955, 'Android Programmer'),
( 957, 'iOS Programmer'),
( 961, 'Back-End Programmer'),
( 962, 'Fullstack Programmer'),
( 971, 'System Architect'),
)),
)
#Thus, we need dictionary/set
T4 = {}
def main():
for k, v in NAMEDTUPLE_ROLES:
for k1, v1 in v:
T4.update ( {k1:v1} )
print (T4[961]) # will display 'Back-End Programmer'
# print (T4) # will display all list of dictionary
main()