2009-08-03 2 views
0

Я хотел сделать что-то вроде SetAttr к классу в методе класса в Python, но класс не существует, так что я в принципе получить:Есть ли способ изменить класс в методе класса в Python?

NameError: global name 'ClassName' is not defined 

Есть ли способ для метода класса, чтобы изменить класс? Нечто подобное, но это на самом деле работает:

class ClassName(object): 
    def HocusPocus(name): 
     setattr(ClassName, name, name) 

    HocusPocus("blah") 
    HocusPocus("bleh") 
+1

Пожалуйста, разместите небольшой, полный пример, который показывает, что вы пытаетесь сделать. –

ответ

5

Методы класса получить класс, передаваемый в качестве первого аргумента:

class Bla(object): 
    @classmethod 
    def cm(cls,value): 
     cls.storedValue = value 

Bla.cm("Hello") 

print Bla.storedValue # prints "Hello" 

Edit: Я думаю, что я понимаю вашу проблему сейчас. Если я правильно, все, что вы хотите сделать это:

class Bla(object): 
    storedValue = "Hello again" 

print Bla.storedValue # prints "Hello again" 

создание класса в Python (довольно много) просто означает:

  1. Создать свежее пространство имен.
  2. Запустите код, который находится внутри тела класса, используя это пространство имен
  3. Поместите все, что осталось в пространстве имен, в класс как атрибуты класса.

С storedValueнаходится в пространстве имен после шага 2, он превратился в атрибут класса в шаге 3.

+0

Есть ли способ запустить cm в теле Bla? – Pablo

+0

Не с предполагаемым результатом (Bla еще не существует). Но если вы просто хотите установить атрибут class storedValue в создании класса, что не так, просто говоря, что storedValue = «Hello» в теле? – balpha

+0

См. Мое редактирование ответа. – balpha

0

Другим способом вы могли бы сделать это было бы использовать class decorator, хотя они доступны только от Python 2.6 и далее IIRC.

Что-то вроде этого:

def addattributes(cls): 
    cls.foobar = 10 
    return cls 

@addattributes 
class MyClass(object): 
    pass 

print MyClass.foobar 

Такого рода это наиболее полезно, когда вы хотите «украсить» ряд классов с некоторыми специфическими функциональными свойствами /. В вашем случае, если вы хотите сделать это только один раз, вы можете просто использовать методы класса, как показано ранее.

0

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

class ClassName(object): 
    def HocusPocus(name): 
     setattr(ClassName, name, property(fget=..., fset=...)) 

    HocusPocus("blah") 
    HocusPocus("bleh") 

это:

class ClassName(object): 

    def HocusPocus(name): 
     return property(fget=..., fset=...) 

    blah = HocusPocus("blah") 
    bleh = HocusPocus("bleh") 

Я предполагаю, что таинственный ... отредактированные части также нуждаются в доступе к name (в противном случае нет необходимости передавать его в качестве аргумента).

Дело в том, что внутри корпуса класса HocusPocus по-прежнему остается лишь функцией (поскольку объект класса еще не существует до тех пор, пока тело класса не завершит выполнение, тело по существу похоже на тело функции, которое работает в его локальном dict [без оптимизаций пространства имен, обычно выполняемых компилятором Python в локалях реальной функции, но это упрощает семантику!]) и, в частности, может вызываться внутри этого тела, может возвращать значение, это значение может быть назначено (к локальной переменной тела класса, которая станет атрибутом класса в конце выполнения тела) и т. д.

Если вы не хотите ClassName.HocusPocus торчать позже, когда вы закончите выполнение его в теле класса просто добавить del заявления (например, в качестве последнего оператора в теле класса):

del HocusPocus 
+0

Проблема в том, что вам нужно повторить: blah и «blah». – Pablo

+0

Другая проблема заключается в том, что я не вижу способа написать fget и fset для получения и установки имени атрибута в объекте. – Pablo

Смежные вопросы