Есть ли лучший / более питонизированный способ сделать это? - PullRequest
3 голосов
/ 15 сентября 2010

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

Но старые привычки из моих дней структурированного / модульного программирования трудно сломать, и я знаю, что должен быть лучший способ написать это. Итак, мне было интересно, хотел бы кто-нибудь взглянуть на следующее и предложить некоторые возможные улучшения, или предложить мне ресурс, который мог бы помочь мне найти их для себя.

Небольшое примечание: корневой класс RandomItems был написан кем-то другим, и я все еще оборачиваюсь вокруг библиотеки itertools. Кроме того, это не весь модуль - просто класс, над которым я работаю, и его предпосылки.

Что ты думаешь?

import itertools
import urllib2
import random
import string

class RandomItems(object):
    """This is the root class for the randomizer subclasses. These
        are used to generate arbitrary content for each of the fields
        in a csv file data row. The purpose is to automatically generate
        content that can be used as functional testing fixture data.
    """
    def __iter__(self):
        while True:
            yield self.next()

    def slice(self, times):
        return itertools.islice(self, times)

class RandomWords(RandomItems):
    """Obtain a list of random real words from the internet, place them
        in an iterable list object, and provide a method for retrieving
        a subset of length 1-n, of random words from the root list.
    """
    def __init__(self):
        urls = [
            "http://dictionary-thesaurus.com/wordlists/Nouns%285,449%29.txt",
            "http://dictionary-thesaurus.com/wordlists/Verbs%284,874%29.txt",
            "http://dictionary-thesaurus.com/wordlists/Adjectives%2850%29.txt",
            "http://dictionary-thesaurus.com/wordlists/Adjectives%28929%29.txt",
            "http://dictionary-thesaurus.com/wordlists/DescriptiveActionWords%2835%29.txt",
            "http://dictionary-thesaurus.com/wordlists/WordsThatDescribe%2886%29.txt",
            "http://dictionary-thesaurus.com/wordlists/DescriptiveWords%2886%29.txt",
            "http://dictionary-thesaurus.com/wordlists/WordsFunToUse%28100%29.txt",
            "http://dictionary-thesaurus.com/wordlists/Materials%2847%29.txt",
            "http://dictionary-thesaurus.com/wordlists/NewsSubjects%28197%29.txt",
            "http://dictionary-thesaurus.com/wordlists/Skills%28341%29.txt",
            "http://dictionary-thesaurus.com/wordlists/TechnicalManualWords%281495%29.txt",
            "http://dictionary-thesaurus.com/wordlists/GRE_WordList%281264%29.txt"
        ]
        self._words = []
        for url in urls:
            urlresp = urllib2.urlopen(urllib2.Request(url))
            self._words.extend([word for word in urlresp.read().split("\r\n")])
        self._words = list(set(self._words)) # Removes duplicates
        self._words.sort() # sorts the list

    def next(self):
        """Return a single random word from the list
        """
        return random.choice(self._words)

    def get(self):
        """Return the entire list, if needed.
        """
        return self._words

    def wordcount(self):
        """Return the total number of words in the list
        """
        return len(self._words)

    def sublist(self,size=3):
        """Return a random segment of _size_ length. The default is 3 words.
        """
        segment = []
        for i in range(size):
            segment.append(self.next())
        #printable = " ".join(segment)        
        return segment

    def random_name(self):
        """Return a string-formatted list of 3 random words.
        """
        words = self.sublist()
        return "%s %s %s" % (words[0], words[1], words[2])

def main():
    """Just to see it work...
    """
    wl = RandomWords()
    print wl.wordcount()
    print wl.next()
    print wl.sublist()
    print 'Three Word Name = %s' % wl.random_name()
    #print wl.get()

if __name__ == "__main__":
    main()

Ответы [ 2 ]

6 голосов
/ 15 сентября 2010

Вот мои пять центов:

  • Конструктор должен называться __init__.
  • Вы можете отменить некоторый код, используя random.sample, он делает то, что ваш next()и sublist() делает, но он предварительно упакован.
  • Переопределите __iter__ (определите метод в вашем классе), и вы можете избавиться от RandomIter.Вы можете прочитать больше об этом в документах (обратите внимание на Py3K, некоторые вещи могут не относиться к более низкой версии).Вы можете использовать yield для этого, который, как вы можете знать, а может и не знать, создает генератор, таким образом, практически не тратя память.
  • random_name может вместо этого использовать str.join.Обратите внимание, что вам может потребоваться преобразовать значения, если они не гарантированно являются строками.Это можно сделать через [str(x) for x in iterable] или встроенным map.
5 голосов
/ 15 сентября 2010

Первая реакция коленного рефлекса: я бы разгрузил ваши жестко запрограммированные URL-адреса в параметр конструктора, передаваемый в класс и, возможно, где-то читал из конфигурации;это позволит легче вносить изменения без необходимости повторного развертывания.

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

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