Dynamically determine base classes on instantiation
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Thu Aug 16 14:04:34 EDT 2012
On Thu, 16 Aug 2012 14:52:30 +0200, Thomas Bach wrote:
> I'm
> querying the crunchbase API which returns JSON data and is rather poorly
> documented. I want to create a data model for the companies listed on
> Crunchbase in order to be able to put the queried data in a data-base.
> As I am too lazy to examine all the data by hand I thought I automatize
> this. I thought that it would be nice to be able to pass a function a
> parsed JSON object (AFAIK these are lists, dicts, strings, ints, floats,
> strs in Python) and it returns me the type of these objects. For the
> simple classes (str, int, float) this is quite trivial: F('foo') should
> return `str' and F(8) should return `int'.
Um, this is utterly trivial for *any* object. Just call type(object), and
it will return the type of the object.
> For a compound object like dict I would like it to return the data
> fields with their type. Hence, F({'foo': 8}) should return {'foo': int},
Your first problem is defining what you consider a compound object. Once
you've done that, it just becomes a matter of recursion:
def recursive_type(obj):
if isinstance(obj, dict):
return dict((k, recursive_type(v)) for (k, v) in obj.items())
elif isinstance(obj, list):
pass # whatever...
else:
return type(obj)
> and given that f = F({'foo': {'bar': 80}}) I would like f to equal to
> {'foo': dict}, with the option to query the type of 'foo' via f.foo,
> where the latter should equal to {'bar': int}. So far, this is not a
> complicated case. But, sometimes a data field on returned data set is
> simply None. Thus, I want to extract the types from another data set and
> merge the two.
>
> So, my question (as far as I can see it, please correct me if I am
> wrong) is less of the "How do I achieve this?"-kind, but more of the
> "What is a clean design for this?"-kind. My intuitive thought was that
> the `merge' function should be a part of the object returned from `F'.
This isn't Java you know. Just write a function to merge the two data
sets and be done with it.
>> Consider your two examples:
>>
>> a = Foo(['a', 'list'])
>> b = Foo({'blah': 8})
>>
>> According to your design:
>>
>> a is a Foo
>> b is a Foo
>
> I actually never said that.
You might not have said that, but that's what instantiation implies. If
you instantiate Foo, you get a Foo instance.
> I simply wanted `a' and `b' to share the
> same function (the `merge' function), I thought that the easiest way to
> achieve this is by letting them share the same name-space.
Or you could you use composition, or a mixin, or straits, or prototypes.
Well, prototypes are hard in Python -- I'm not sure how you would go
about doing that.
--
Steven
More information about the Python-list
mailing list