Добавление атрибутов класса с помощью для цикла в Python

Я пытался генерировать класс из словаря:

class attr:
    for key in objects_type:
        setattr(attr, key, lambda cl: list())

Это дает ошибку, что attr не определяется во время для цикла. Я знаю, что мог записать:

class attr:
    pass
for key in objects_type:
    setattr(attr, key, lambda cl: list())

Но я уверен, что не забываю видеть код, подобный первому примеру где-нибудь. Кто-либо знает, возможно ли записать что-то подобное первой форме?

11
задан Casebash 15 February 2010 в 10:58
поделиться

5 ответов

Хотя это не очень элегантно, вы можете использовать locals () : ​​

>>> class c(object):
...     for i in range(10):
...         locals()['A' + str(i)] = i
... 
>>> c.A0
0
>>> c.A7
7
9
ответ дан 3 December 2019 в 06:21
поделиться

Я точно не знаю, что вы делаете. Я могу привести пример добавления атрибутов класса к классу в цикле for:

attributes = ('x', 5), ('y', 6), ('name', 'Cls')

class Cls:
  pass
for key, value in attributes:
  setattr(Cls, key, value)

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

3
ответ дан 3 December 2019 в 06:21
поделиться
class Attr:
  def __init__(self):
    for key in objects_type:
      setattr(Attr, key, lambda cl: list())
1
ответ дан 3 December 2019 в 06:21
поделиться
newmeths = {
  'two': lambda self: 2,
}

class MC(type):
  def __init__(cls, name, bases, dict):
    for k, v in newmeths.iteritems():
      setattr(cls, k, v)
    super(MC, cls).__init__(name, bases, dict)

class C(object):
  __metaclass__ = MC
  pass

c=C()
print c.two()
3
ответ дан 3 December 2019 в 06:21
поделиться

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

classDict = {}
for i in range(2):
    classDict["func%s"%(i+1)] = lambda self:"X"

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

class Attr2(object):
    pass

for n,v in classDict.iteritems():
    setattr(Attr2, n, v)

print Attr2().func1(), Attr2().func2()

или лучше просто создать класс на лету, например.

Attr3 = type("Attr3",(), classDict)
print Attr3().func1(), Attr3().func2()

или, если вы хотите использовать метакласс, например,

class AttrMeta(type):
    def __new__(cls, name, bases, dct):
        dct.update(classDict)
        return type.__new__(cls, name, bases, dct)

class Attr4(object):
    __metaclass__ = AttrMeta

print Attr4().func1(), Attr4().func2()
3
ответ дан 3 December 2019 в 06:21
поделиться
Другие вопросы по тегам:

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