Более короткий способ сделать свойства доступными только для чтения - PullRequest
0 голосов
/ 29 июня 2018

Я читал на многих сайтах, что если я хочу создать свойство только для чтения, я должен использовать декоратор property.

Как это:

class MyClass(object):
  def __init__(self):
    self._a = None

  @property
  def a(self):
    return self._a

Я думаю, что это хорошее решение, если у меня есть только 1-3 свойства только для чтения в классе. Но что, если у меня их может быть 10? Это привело бы к 40 дополнительным строкам кода, чтобы пометить их как доступные только для чтения. На мой взгляд, это не совсем подходит для Python, который должен быть языком, где вам не нужно писать большую кучу кода, чтобы делать мелочи.

Нет ли в Python более короткого способа сделать свойство доступным только для чтения?

1 Ответ

0 голосов
/ 29 июня 2018

По крайней мере, вы можете просто вызвать property как функцию, а не использовать ее в качестве декоратора. В то же время вы можете хранить базовые значения в списке или в тексте, а не в виде отдельных атрибутов.

class MyClass(object):
    def __init__(self):
        self._values = [...]

    a = property(lambda self: self._values[0])
    b = property(lambda self: self._values[1])
    # etc

Однако свойство только для чтения не обязательно должно хранить свое значение в экземпляре dict; просто закодируйте значение прямо в получателе:

class MyClass(object):

    a = property(lambda self: "foo")
    b = property(lambda self: "bar") 

А затем обернуть вызов свойства в другую функцию:)

def constant(value):
    def _(self):
        return value
    return property(_)

class MyClass(object):
    a = constant("foo")
    b = constant("bar")

Вот свойство только для чтения на Python, смоделированное по примеру, показанному в https://docs.python.org/3/howto/descriptor.html#properties:

class Constant(object):
    def __init__(self, value)
        def _(self):
            return value
        self.fget = _

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        return self.fget(obj)

Это, вероятно, проще, чем создать подкласс property и переопределить __set__ и __del__, чтобы "реализовать их". Но мне больше нравится моя идея обертки вокруг обычного свойства.

...