Создание свойств экземпляра класса из словаря?

там сжатый способ получить случайную запись от таблицы SQL-сервера?

Да

SELECT TOP 1 * FROM table ORDER BY NEWID()

Объяснение

А NEWID() сгенерирован для каждой строки, и таблица тогда отсортирована по нему. Первая запись возвращается (т.е. запись с "самым низким" GUID).

Примечания

  1. GUID сгенерированы как псевдослучайные числа начиная с версии четыре:

    UUID версии 4 предназначен для генерации UUID от действительно случайных или псевдослучайных чисел.

    алгоритм следующие:

    • Набор два старших значащих бита (биты 6 и 7) clock_seq_hi_and_reserved для обнуления и один, соответственно.
    • Набор четыре старших значащих бита (биты 12 - 15) time_hi_and_version поля к 4-разрядному номеру версии от Раздела 4.1.3.
    • Набор все другие биты к случайным образом (или псевдослучайным образом) выбранные значения.

    А Универсально Уникальный идентификатор (UUID) Пространство имен УРНЫ - RFC 4122

  2. альтернатива SELECT TOP 1 * FROM table ORDER BY RAND() не будет работать, как можно было бы думать. RAND() возвраты одно единственное значение на запрос, таким образом все строки совместно используют то же значение.

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

  4. Типичная производительность составляет меньше чем 10 секунд приблизительно для 1 000 000 строк — конечно, в зависимости от системы. Обратите внимание, что невозможно поразить индекс, таким образом производительность будет относительно ограничена.

55
задан martineau 12 June 2017 в 20:48
поделиться

6 ответов

Вы можете использовать setattr (будьте осторожны: не каждая строка допустимое имя атрибута!):

>>> class AllMyFields:
...     def __init__(self, dictionary):
...         for k, v in dictionary.items():
...             setattr(self, k, v)
... 
>>> o = AllMyFields({'a': 1, 'b': 2})
>>> o.a
1

Изменить: позвольте мне объяснить разницу между приведенным выше кодом и ответом SilentGhost . Приведенный выше фрагмент кода создает класс, атрибуты экземпляра которого основаны на данном словаре. Код SilentGhost создает класс, атрибуты класса которого основаны на заданном словаре.

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

92
ответ дан 26 November 2019 в 17:43
поделиться

Использование именованных кортежей (Python 2.6):

>>> from collections import namedtuple

>>> the_dict = {'Field1': 3, 'Field2': 'b', 'foo': 4.9}
>>> fields = ' '.join(the_dict.keys())
>>> AllMyFields = namedtuple('AllMyFields', fields)
>>> instance = AllMyFields(**the_dict)

>>> print instance.Field1, instance.Field2, instance.foo
3 b 4.9
5
ответ дан 26 November 2019 в 17:43
поделиться

Вы могли создайте подкласс dict , который позволяет искать атрибуты для ключей:

class AttributeDict(dict):
    def __getattr__(self, name):
        return self[name]

q = AttributeDict({ 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 })
print q.Field1              
print q.Field2              
print q.RandomField

Если вы попытаетесь найти атрибут, который dict уже имеет (скажем, ключи или get ), вы получите атрибут класса dict (метод). Если запрашиваемый ключ не существует в классе dict , то будет вызван метод __ getattr __ , который выполнит поиск вашего ключа.

4
ответ дан 26 November 2019 в 17:43
поделиться
>>> q = { 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }
>>> q = type('allMyFields', (object,), q)
>>> q.Field1
3000

документы для типа хорошо объясняют, что здесь происходит (см. Использование в качестве конструктора).

редактировать : в случае, если вам нужны переменные экземпляра, также работает:

>>> a = q()             # first instance
>>> a.Field1
3000
>>> a.Field1 = 1
>>> a.Field1
1
>>> q().Field1           # second instance
3000
32
ответ дан 26 November 2019 в 17:43
поделиться

Вы также можете использовать dict.update вместо ручного зацикливания элементов (а если вы зацикливаете, то iteritems лучше).

class allMyFields(object):
    # note: you cannot (and don't have to) use self here
    Field1 = None
    Field2 = None

    def __init__(self, dictionary):
        self.__dict__.update(dictionary)

q = { 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }
instance = allMyFields(q)

print instance.Field1      # => 3000
print instance.Field2      # => 6000
print instance.RandomField # => 5000
9
ответ дан 26 November 2019 в 17:43
поделиться

Используйте setattr для изящного способа. Самый простой способ - обновить внутренний словарь экземпляра:

>>> class A(object):
...    pass
...
>>> a = A()
>>> a.__dict__.update({"foo": 1, "bar": 2})
>>> a.foo
1
>>> a.bar
2
>>>
3
ответ дан 26 November 2019 в 17:43
поделиться
Другие вопросы по тегам:

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