2010-08-26 2 views
0

Предположим, у меня есть класс, и я хочу ссылаться на некоторые элементы в '__dict__ (например, я хочу скопировать dict и удалить атрибут, который не может быть маринованный), изнутри класс.python: ссылки «частные» переменные организованным образом

Проблема заключается в том, эти атрибуты являются «закрытыми», поэтому мой код заканчивает тем, как так

class MyClasss(object): 
    def __init__(self): 
      self.__prv=1 
    def __getstate__(self): 
      ret=self.__dict__.copy() 
      del ret['_MyClass__prv'] 

я ссылаться на имя класса явно в дель заявлении, которое выглядит немного некрасиво для меня. Есть ли что-то приятнее? что-то вроде MyClass.getPrivateString('prv')

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

+1

В Python нет никаких частных атрибутов, так как ваши кавычки, похоже, показывают, что вы знаете. Я подозреваю (но не знаю), что двойное подчёркивание должно было предотвращать непреднамеренный доступ к атрибутам '__machinery__', таким как' __getstate__'. – msw

+3

@msw [mangling only происходит, если атрибут начинается с двух символов подчеркивания, и не заканчивается двумя символами подчеркивания.] (Http://docs.python.org/reference/expressions.html#atom-identifiers) Специальные атрибуты, такие как '__getstate__' НЕ искажены. –

+4

[PEP8] (http://www.python.org/dev/peps/pep-0008/) может многое сказать о соглашениях об именах и о том, когда использовать имена с одним и двумя символами в именах. В этой ситуации я бы не использовал двойные подчеркивания. –

ответ

0

В конце концов, я использовал вариант решения thieger в

del ret["_%s__%s" % (MyClasss.__name__, "prv")] 

Я думаю, что это самый надежный способ, которым я могу написать, что часть кода, кроме отказа от коверкая, что может быть правильно делать, но я спрашивал, что делать, если у вас на самом деле есть mangling :)

6

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

class MyClasss(object): 
    def __init__(self): 
      self._prv=1 
    def __getstate__(self): 
      ret=self.__dict__.copy() 
      del ret['_prv'] 
+0

спасибо, я мог бы использовать этот совет. , но я бы очень хотел получить ответ на мой исходный вопрос, с помощью mangling :) – olamundo

+0

Проверьте мой ответ, я попытался разобраться с именем mangling по-другому. – jbernadas

+2

@noam: Разве это не так, как просить болеутоляющего, так что больно меньше, пока вы ударяете себя молотком? @ jon-eric: спасибо за указатель на документы. – msw

0

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

class X: 
    def __init__(self): 
    self.__prv = 0 

    def del_privates(self): 
    del self.__prv 

    def __getstate__(self): 
    other = X() 
    other.__dict__ = self.__dict__.copy() 
    other.del_privates() 
    return other.__dict__ 

После вызова __getstate__, возвращаемый ДИКТ не будет иметь __prv член, так как он стирается, когда вызывается other.del_privates().

+0

Или, еще лучше, просто не обращайтесь с именем mangling. – habnabit

+0

Я знаю, что это лучше, по каким-то причинам название mangling. Однако я ответил, потому что ОП спросил, как это сделать. – jbernadas

0

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

del ret["_%s__%s" % (self.__class__.__name__, "prv")] 
+1

Это прерывается с помощью подкласса. – habnabit

-1

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

class MyClasss(object): 
    def __init__(self): 
      self._prv_x=1 
      self._prv_y=1 
    def __getstate__(self): 
      return dict((k,v) for k,v in vars(self).items() if not k.startswith("_prv_")) 

в python2.7 +

def __getstate__(self): 
      return {k:v for k,v in vars(self).items() if not k.startswith("_prv_")} 
+1

Эту конвенцию уже существует: одно главное подчеркивание. – habnabit

+0

@Aaron, OP нуждается в способе различать переменные, которые не должны быть маринованными. Зоп использует ту же идею. –

+0

так почему бы не использовать установленное соглашение единственного ведущего подчеркивания? – habnabit

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