Reputation: 2840
The goal is to build a class with an __init__
method that will allow to create objects which will be initialized with a specific dictionary.
Details:
A file mydicts.py
is a collection of various dictionaries.
The object built from the class that I intent to create will be initialized to one of the dictionaries from mydicts.py
.
mydicts.py
example:
dict1 = {k1:v1, k2:v2,...,kn:vn}
dict2 = {k1:v1, k2:v2,...,km:vm}
etc.
My attempts:
class Example(dict):
def __init__(self, dictx):
self.dictx = getattr(__import__("mydicts", fromlist=['m']), dictx)
Results:
e = Example('dict1')
print e
{} # <- got empty dictionary. Want {k1:v1, k2:v2,...,kn:vn}
The goal is to create objects such that:
a = Example(dict1)
print a
# {k1:v1, k2:v2,...,kn:vn}
b = Example(dict2)
print b
# {k1:v1, k2:v2,...,km:vm}
Upvotes: 1
Views: 700
Reputation: 43487
I think you are making this far more complicated than it need be. Noting the manual says:
Direct use of
__import__()
is rare, except in cases where you want to import a module whose name is only known at runtime.
But you do know the module name at loading time, your data definition just has too many variable names. Much clearer would be my_dicts.py
:
my_dicts = [
{k1:v1, k2:v2,...,kn:vn},
{k1:v1, k2:v2,...,km:vm},
…
]
and example.py
:
import my_dicts
class Example(dict):
def __init__(self, n):
"""Returns an Example instance loaded with the nth element
of my_dict."""
super(Example, self).__init__(my_dicts.my_dicts[n])
Upvotes: 1
Reputation:
Since you did not define a custom __str__
method for your class, print
is calling the __str__
method of the parent class dict
. Moreover, this is causing Python to print the empty dictionary created by the parent class in dict.__new__
instead of the dictionary that you have stored in self.dictx
.
Because your class inherits from dict
, you should be passing the dictionary returned by getattr
to the __init__
method of the parent class. You can use super
for this:
class Example(dict):
def __init__(self, dictx):
dct = getattr(__import__("__main__", fromlist=['m']), dictx)
super(Example, self).__init__(dct)
This will initialize the parent class with data taken from dct
. In other words, the empty dictionary has been replaced with the dictionary returned by getattr
. So, when print
calls the parent's __str__
method, the correct output will be given:
>>> dict1 = {'k1':'v1', 'k2':'v2', 'kn':'vn'}
>>> class Example(dict):
... def __init__(self, dictx):
... dct = getattr(__import__("__main__", fromlist=['m']), dictx)
... super(Example, self).__init__(dct)
...
>>> e = Example('dict1')
>>> print e
{'k2': 'v2', 'k1': 'v1', 'kn': 'vn'}
>>>
An alternate solution would be to define a custom __str__
method for your class that returns self.dictx
as a string:
class Example(dict):
def __init__(self, dictx):
self.dictx = getattr(__import__("mydicts", fromlist=['m']), dictx)
def __str__(self):
return str(self.dictx)
Note however that if you use this approach, there isn't really a reason to inherit from dict
since your class is not a new type of dictionary; it just has a dictionary stored as an attribute.
Upvotes: 2