Что простой способ состоит в том, чтобы создать тривиальный одноразовый объект Python?

Я использовал https://github.com/facebookgo/inject для DI и https://github.com/golang/mock для насмешек. Например:

// some_entity_dao.go
type SomeEntity interface {
    Find(ctx context.Context, condition *model.SomeEntity) (*model.SomeEntity, error)
    FindAll(ctx context.Context, condition *model.SomeEntity) ([]*model.SomeEntity, error)
    Save(ctx context.Context, data *model.SomeEntity) error
    Update(ctx context.Context, condition *model.SomeEntity, data *model.SomeEntity) error
    Delete(ctx context.Context, condition *model.SomeEntity) error
}

И сгенерировать фиктивную реализацию, используя:

//go:generate mockgen -source=./some_entity_dao.go -destination=./some_entity_dao_mock_impl.go -package dao

Затем используйте эту фиктивную реализацию при написании юнит-тестов.

9
задан mhagger 17 October 2008 в 10:47
поделиться

10 ответов

Учитывая Ваши требования, я сказал бы, что пользовательский класс является Вашим лучшим выбором:

class options(object):
    VERBOSE = True
    IGNORE_WARNINGS = True

if options.VERBOSE:
    # ...

Чтобы быть завершенным, другой подход использовал бы отдельный модуль, т.е. options.py инкапсулировать Ваши значения по умолчанию опции.

options.py:

VERBOSE = True
IGNORE_WARNINGS = True

Затем в main.py:

import options

if options.VERBOSE:
    # ...

Это имеет функцию удаления некоторой помехи из Вашего сценария. Значения по умолчанию легко найти и измениться, поскольку они загорожены в их собственном модуле. Если позже Ваше приложение выросло, можно легко получить доступ к опциям от других модулей.

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

8
ответ дан 4 December 2019 в 06:04
поделиться

Модуль наборов вырастил функцию namedtuple в 2,6:

import collections
opt=collections.namedtuple('options','VERBOSE IGNORE_WARNINGS')
myoptions=opt(True, False)

>>> myoptions
options(VERBOSE=True, IGNORE_WARNINGS=False)
>>> myoptions.VERBOSE
True

namedtuple неизменен, таким образом, можно только присвоить значения полей при создании его.

В более ранних версиях Python можно создать пустой класс:

class options(object):
    pass

myoptions=options()
myoptions.VERBOSE=True
myoptions.IGNORE_WARNINGS=False
>>> myoptions.IGNORE_WARNINGS,myoptions.VERBOSE
(False, True)
14
ответ дан 4 December 2019 в 06:04
поделиться

Почему не просто используют optparse:

from optparse import OptionParser
[...]
parser = OptionParser()
parser.add_option("-f", "--file", dest="filename",
              help="write report to FILE", metavar="FILE")
parser.add_option("-q", "--quiet",
              action="store_false", dest="verbose", default=True,
              help="don't print status messages to stdout")

(options, args) = parser.parse_args()

file = options.filename
if options.quiet == True:
    [...]
7
ответ дан 4 December 2019 в 06:04
поделиться

Если Вы настаиваете на том, чтобы не иметь необходимость определить класс, можно злоупотребить некоторыми существующими классами. Большинство объектов принадлежит "модернизированным" классам, которые не имеют dict, но функции могут иметь произвольные атрибуты:

>>> x = lambda: 0   # any function will do
>>> x.foo = 'bar'
>>> x.bar = 0
>>> x.xyzzy = x
>>> x.foo
'bar'
>>> x.bar
0
>>> x.xyzzy
<function <lambda> at 0x6cf30>

Одна проблема состоит в том, что функции уже имеют некоторые атрибуты, таким образом, dir (x) немного грязен:

>>> dir(x)
['__call__', '__class__', '__delattr__', '__dict__', '__doc__',
'__get__', '__getattribute__', '__hash__', '__init__',
'__module__', '__name__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__str__', 'foo',
'func_closure', 'func_code', 'func_defaults', 'func_dict',
'func_doc', 'func_globals', 'func_name', 'xyzzy']
6
ответ дан 4 December 2019 в 06:04
поделиться

Просто сделайте модуль по имени Options.py и импортируйте его. Поместите свои значения опций по умолчанию там как глобальные переменные.

3
ответ дан 4 December 2019 в 06:04
поделиться

Я использую attrdict:

class attrdict(dict):
    def __init__(self, *args, **kwargs):
        dict.__init__(self, *args, **kwargs)
        self.__dict__ = self

В зависимости от Вашей точки зрения Вы, вероятно, думаете, что это - или большой клудж или довольно умный. Но независимо от того, что Вы думаете, это действительно делает для симпатичного кода и совместимо с dict:

>>> ad = attrdict({'foo': 100, 'bar': 200})
>>> ad.foo
100
>>> ad.bar
200
>>> ad.baz = 'hello'
>>> ad.baz
'hello'
>>> ad
{'baz': 'hello', 'foo': 100, 'bar': 200}
>>> isinstance(ad, dict)
True
5
ответ дан 4 December 2019 в 06:04
поделиться

Когда лучшие практики идут, Вы действительно более обеспечены с одной из опций в ответе David Eyk.

Однако для ответа на вопрос можно создать одноразовый класс с помощью type функция:

options = type('Options', (object,), { 'VERBOSE': True })()
options.IGNORE_WARNINGS = False

Обратите внимание, что можно предоставить первоначальный словарь, или просто оставить это пустым.

Options = type('Options', (object,), {})
options = Options()
options.VERBOSE = True
options.IGNORE_WARNINGS = False

Не очень pythonic.

4
ответ дан 4 December 2019 в 06:04
поделиться

Упрощая предложение davraamides, можно было использовать следующее:

class attrdict2(object):
    def __init__(self, *args, **kwargs):
        self.__dict__.update(*args, **kwargs)

который

  1. Не таким образом топорен.

  2. Не загрязняет пространство имен каждого объекта со стандартными методами dict; например, ad.has_key не определяется для объектов типа attrdict2.

Между прочим, еще легче инициализировать экземпляры attrdict или attrdict2:

>>> ad = attrdict2(foo = 100, bar = 200)

Предоставленный, attrdict2 не совместимо с a dict.

Если Вам не нужно волшебное поведение инициализации, можно даже использовать

class attrdict3(object):
    pass

ad = attrdict3()
ad.foo = 100
ad.bar = 200

Но я все еще надеялся на решение, которое не требует вспомогательного класса.

2
ответ дан 4 December 2019 в 06:04
поделиться

Можно использовать

class options(object):
    VERBOSE = True
    IGNORE_WARNINGS = False

options.VERBOSE = False

if options.VERBOSE:
    ...

, использование самого объекта класса (не экземпляр класса!) как место для хранения отдельных опций. Это кратко и удовлетворяет все требования, но это походит на неправильное употребление понятия класса. Это также привело бы к беспорядку если пользователь, который инстанцируют options класс.

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

1
ответ дан 4 December 2019 в 06:04
поделиться

Абсолютно самый простой класс, чтобы сделать задание:

class Struct:
    def __init__(self, **entries): 
        self.__dict__.update(entries)

Это может позже использоваться как:

john = Struct(name='john doe', salary=34000)
print john.salary

namedtuple (как другой прокомментировал предложенный), более усовершенствованный класс, который дает Вам больше функциональности. Если Вы все еще используете Python 2.5, реализация 2.6's namedtuple на основе, может быть найден по http://code.activestate.com/recipes/500261/

1
ответ дан 4 December 2019 в 06:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: