Добавление атрибутов класса с помощью цикла for в Python - PullRequest
10 голосов
/ 15 февраля 2010

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

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

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

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

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

Ответы [ 5 ]

7 голосов
/ 15 февраля 2010

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

>>> class c(object):
...     for i in range(10):
...         locals()['A' + str(i)] = i
... 
>>> c.A0
0
>>> c.A7
7
3 голосов
/ 15 февраля 2010

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

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 голосов
/ 15 февраля 2010
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()
2 голосов
/ 15 февраля 2010

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

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

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

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

1 голос
/ 15 февраля 2010
class Attr:
  def __init__(self):
    for key in objects_type:
      setattr(Attr, key, lambda cl: list())
...