Python: ссылки на имена «частных» переменных организованным образом - PullRequest
2 голосов
/ 27 августа 2010

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

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

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

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

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

Ответы [ 5 ]

6 голосов
/ 27 августа 2010

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

class MyClasss(object):
    def __init__(self):
          self._prv=1
    def __getstate__(self):
          ret=self.__dict__.copy()
          del ret['_prv']
1 голос
/ 30 августа 2010

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

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

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

1 голос
/ 27 августа 2010

Вы можете попытаться создать копию объекта, стереть его личные атрибуты, а затем вернуть __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__ возвращенный dict не будет иметь члена __prv, поскольку он стирается при вызове other.del_privates().

0 голосов
/ 27 августа 2010

Лучше использовать собственное соглашение об именах для этих атрибутов, таких как _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_")}
0 голосов
/ 27 августа 2010

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

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