开发者

Declaring types for complex data structures in python

开发者 https://www.devze.com 2023-01-28 05:44 出处:网络
I am quite new to python programming (C/C++ background). I\'m writing code where I need to use complex data structures like dictionaries of dictionaries of lists.

I am quite new to python programming (C/C++ background). I'm writing code where I need to use complex data structures like dictionaries of dictionaries of lists. The issue is that when I must use these objects I barely remember their structure and so how to access them. This makes it diff开发者_开发百科icult to resume working on code that was untouched for days. A very poor solution is to use comments for each variable, but that's very inflexible. So, given that python variables are just pointers to memory and they cannot be statically type-declared, is there any convention or rule that I could follow to ease complex data structures usage?


If you use docstrings in your classes then you can use help(vargoeshere) to see how to use it.


Whatever you do, do NOT, I repeat, do NOT use Hungarian Notation! It causes severe brain & bit rot.

So, what can you do? Python and C/C++ are quite different. In C++ you typically handle polymorphic calls like so:

void doWithFooThing(FooThing *foo) {
    foo->bar();
}

Dynamic polymorphism in C++ depends on inheritance: the pointer passed to doWithFooThing may point only to instances of FooThing or one of its subclasses. Not so in Python:

def do_with_fooish(fooish):
    fooish.bar()

Here, any sufficiently fooish thing (i.e. everything that has a callable bar attribute) can be used, no matter how it is releated to any other fooish thing through inheritance.

The point here is, in C++ you know what (base-)type every object has, whereas in Python you don't, and you don't care. What you try to achieve in Python is code that is reusable in as many situations as possible without having to force everthing under the rigid rule of class inheritance. Your naming should also reflect that. You dont write:

def some_action(a_list):
    ...

but:

def some_action(seq):
    ...

where seq might be not only a list, but any iterable sequence, be it list, tuple, dict, set, iterator, whatever.

In general, you put emphasis on the intent of your code, instead of its the type structure. Instead of writing:

dict_of_strings_to_dates = {}

you write:

users_birthdays = {}

It also helps to keep functions short, even more so than in C/C++. Then you'll be easily able to see what's going on.

Another thing: you shouldn't think of Python variables as pointers to memory. They're in fact dicionary entries:

assert foo.bar == getattr(foo, 'bar') == foo.__dict__['bar']

Not always exactly so, I concur, but the details can be looked up at docs.python.org.

And, BTW, in Python you don't declare stuff like you do in C/C++. You just define stuff.


I believe you should take a good look some of your complex structures, what you are doing with them, and ask... Is This Pythonic? Ask here on SO. I think you will find some cases where the complexity is an artifact of C/C++.


Include an example somewhere in your code, or in your tests.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号