основные проблемы для тех, кто переходит от статического языка (java / c #) к динамическому языку, такому как python - PullRequest
6 голосов
/ 13 сентября 2010

Каковы основные проблемы для тех, кто переходит от статического языка (java / c #) к динамическому языку, например, python?

Кажется, круто, как все можно сделать, кроме переименования метода или добавления / удаленияпараметры кажутся такими рискованными!

Является ли единственным решением для написания тестов для каждого метода?

Ответы [ 3 ]

3 голосов
/ 13 сентября 2010

«Является ли единственным решением для написания тестов для каждого метода?»

Вы говорите, что не написали тесты для каждого метода в Java?

Если вы написали тесты для каждого метода в Java, то - ну - ничего не изменится, не так ли?

переименование метода кажется рискованным!

Правильно.Не делайте этого.

добавление / удаление параметров кажется таким рискованным!

Что?Вы говорите о дополнительных параметрах?Если это так, то наличие нескольких перегруженных имен в Java кажется рискованным и запутанным.Опциональные параметры кажутся более простыми.


Если вы будете искать в SO наиболее распространенные вопросы Python, вы обнаружите, что некоторые вещи являются хроническими.

  • Как обновить PYTHONPATH.

  • Почему некоторые случайные вычисления с плавающей запятой не совпадают с математической абстракцией, которую можно указать.

  • Использование Python 3 и ввод кода из учебника по Python 2.

  • Почему в Python нет сверхсложных объявлений protected, private и public.

  • Почему у Python нет типа enum.

Кажется, что хроническая проблема № 1 использует изменяемые объекты в качестве значений по умолчанию для функции.Просто избегайте этого.

2 голосов
/ 14 сентября 2010

Я бы сказал, что номер один Гоча пытается написать статически типизированный код на динамическом языке.

Не стесняйтесь использовать идентификатор для указания на строку, а затем список в автономных разделахкод

keys = 'foo bar foobar' # Imagine this coming in as an argument
keys = keys.split() # Now the semantically chose name for the argument can be 
                    # reused As the semantically chosen name for a local variable

не стесняйтесь обращаться с функциями как с обычными значениями: они есть.Возьми следующий парсер.Предположим, что мы хотим обрабатывать все теги заголовка одинаково, а теги ul - как теги ol.

class Parser(HTMLParser):
    def __init__(self, html):
        self.feed(html)

    def handle_starttag(self, tag, attrs):
        parse_method = 'parse_' + tag    
        if hasattr(self, parse_method):  
            getattr(self, parse_method)(attrs)


    def parse_list(self, attrs):
        # generic code

    def parse_header(self, attrs):
       # more generic code

    parse_h1 = parse_h2 = parse_h3 = parse_h4 = parse_h5 = parse_h6 = parse_header
    parse_ol = parse_ul = parse_list

Это можно сделать, используя менее общий код в методе handle_starttag в языке, подобном java, отслеживаякакие теги соответствуют тому же методу, но затем, если вы решите, что хотите обрабатывать теги div, вы должны добавить это в логику диспетчеризации.Здесь вы просто добавляете метод parse_div и все готово.

Не проверяйте тип! Утиный тип!

def funtion(arg):
    if hasattr(arg, 'attr1') and hasattr(arg, 'attr2'):
         foo(arg):
    else:
         raise TypeError("arg must have 'attr1' and 'attr2'")

вместо isinstance(arg, Foo).Это позволяет вам передавать любой объект с attr1 и attr2.Это позволяет вам, например, передать класс трассировки, обернутый вокруг объекта, в целях отладки.Вам придется изменить класс, чтобы сделать это в Java AFAIK.

Как указал THC4k, другой (более питонический) способ сделать это - идиома EAPF .Мне это не нравится, потому что я люблю ловить ошибки как можно раньше.Тем не менее, это более эффективно, если вы ожидаете, что код будет редко давать сбой.Никому не говорите, что мне это не нравится, хотя наши перестанут думать, что я знаю, как писать на Python.Вот пример любезности THC4k.

try: 
    foo(arg): 
except (AttributeError, TypeError): 
    raise InvalidArgumentError(foo, arg)

Это вопрос о том, должны ли мы ловить AttributeError и TypeError или просто позволить им распространяться куда-то, кто знает, как с ними обращаться, но этопросто пример, поэтому мы позволим ему летать.

2 голосов
/ 14 сентября 2010

Некоторые вещи, которые меня поразили, когда я впервые пробовал Python (в основном из Java-фона):

  1. Запись Pythonic код. Используйте идиомы, рекомендуемые для Python, вместо того, чтобы делать это старым способом Java / C. Это больше, чем просто косметическая или догматическая проблема. На самом деле Pythonic код на практике намного быстрее, чем C-подобный код. На самом деле, IMHO, многие из понятий «Python is slow» разворачиваются из-за того, что неопытные программисты пытались кодировать Java / C в Python и в итоге получили большой удар по производительности и поняли, что Python ужасно медленно Используйте списки и карту / фильтруйте / уменьшайте всякий раз, когда это возможно.

  2. Успокойтесь с мыслью, что функции действительно являются объектами. Передавайте их как обратные вызовы, заставляйте функции возвращать функции, узнавайте о замыканиях и т. Д.

  3. Есть много классных и почти волшебных вещей, которые вы можете сделать в Python, например, методы переименования, как вы упомянули. Эти вещи хороши для демонстрации возможностей Python, но на самом деле не нужны, если они вам не нужны. Действительно, как указал С. Лотт, лучше избегать вещей, которые кажутся рискованными.

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