Объявление типов для сложных структур данных в Python - PullRequest
3 голосов
/ 02 декабря 2010

Я довольно новичок в программировании на Python (фон C / C ++).Я пишу код, где мне нужно использовать сложные структуры данных, такие как словари словарей списков.Проблема в том, что когда я должен использовать эти объекты, я плохо помню их структуру и то, как получить к ним доступ.Это затрудняет возобновление работы с кодом, который оставался нетронутым в течение нескольких дней.Очень плохое решение - использовать комментарии для каждой переменной, но это очень негибко.Итак, учитывая, что переменные python являются просто указателями на память и они не могут быть статически объявлены по типу, есть ли какое-либо соглашение или правило, которому я мог бы следовать, чтобы облегчить использование сложных структур данных?

Ответы [ 4 ]

3 голосов
/ 02 декабря 2010

Если вы используете строки документации в своих классах, вы можете использовать help(vargoeshere), чтобы увидеть, как его использовать.

2 голосов
/ 02 декабря 2010

Что бы вы ни делали, НЕ повторяю, НЕ используйте венгерскую нотацию!Это вызывает сильную головную боль и гниение.

Итак, что вы можете сделать?Python и C / C ++ довольно разные.В C ++ вы обычно обрабатываете полиморфные вызовы, например, так:

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

Динамический полиморфизм в C ++ зависит от наследования: указатель, передаваемый в doWithFooThing, может указывать только на экземпляры FooThing или один из его подклассов.В Python это не так:

def do_with_fooish(fooish):
    fooish.bar()

Здесь можно использовать любую достаточно глупую вещь (то есть все, что имеет атрибут вызываемого бара), независимо от того, как она передается любой другой глупой вещи посредством наследования.

Дело в том, что в C ++ вы знаете, какой (базовый) тип имеет каждый объект, тогда как в Python это не так, и вам все равно.То, чего вы пытаетесь достичь в Python, - это код, который можно использовать повторно во всех возможных ситуациях, не прибегая к принудительному правилу наследования классов.Ваше наименование должно также отражать это.Вы не пишете:

def some_action(a_list):
    ...

, но:

def some_action(seq):
    ...

, где seq может быть не только списком, но и любой итерируемой последовательностью, будь то список, кортеж, dict, set, iterator,что угодно.

В общем, вы делаете акцент на предназначении вашего кода, а не на его структуре типов.Вместо того, чтобы писать:

dict_of_strings_to_dates = {}

вы пишете:

users_birthdays = {}

Это также помогает сохранять короткие функции, даже в большей степени, чем в C / C ++.Тогда вы легко сможете увидеть, что происходит.

Другое дело: вы не должны думать о переменных Python как о указателях на память.Они на самом деле являются диктионными записями:

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

Не всегда точно так что, я согласен, но подробности можно посмотреть на docs.python.org .

И, кстати, в Python вы не объявляете вещи, как вы делаете в C / C ++.Вы просто определяете вещи.

1 голос
/ 02 декабря 2010

Полагаю, вам следует хорошенько взглянуть на некоторые из ваших сложных структур, что вы делаете с ними, и спросить ... Является ли это Pythonic?Спросите здесь на SO.Я думаю, вы найдете несколько случаев, когда сложность является артефактом C / C ++.

0 голосов
/ 02 декабря 2010

Включите пример где-нибудь в свой код или в свои тесты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...