Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将实例字段转换为属性_Python_Properties_Python Decorators_Readonly Attribute - Fatal编程技术网

Python 将实例字段转换为属性

Python 将实例字段转换为属性,python,properties,python-decorators,readonly-attribute,Python,Properties,Python Decorators,Readonly Attribute,我想将对象的所有实例字段转换为属性(仅限getter),以便使它们成为只读的。字段可以由子类定义 我怎样才能做到这一点 class SomeClass(object): def __init__(self, foo, bar): self.foo = foo self.bar = bar convert_all_instance_fields_into_properties(self) # implementation ? Py

我想将对象的所有实例字段转换为属性(仅限getter),以便使它们成为只读的。字段可以由子类定义

我怎样才能做到这一点

class SomeClass(object):

    def __init__(self, foo, bar):

        self.foo = foo
        self.bar = bar

        convert_all_instance_fields_into_properties(self)   # implementation ?

Python中没有“private”这样的东西。如果你愿意并且足够努力,你可以提取任何东西

有两个级别的半私有:

  • 一个下划线前缀供内部使用,通常可在外部访问,但大多数IDE将在其下方加下划线,并警告不推荐使用
  • 伪私有的两个下划线前缀,如果有人真的想要它,但很难看,仍然可以访问
大多数情况下,您只需要一个下划线-人们只有在认为自己真正需要时才会访问它

在我正在使用的代码中,我看到两个下划线仅用于封装延迟加载的属性(一个下划线是“getter”并检查变量是否已加载)

请记住,即使使用“getter”,您也将返回一个对象,除非您自己返回一个副本。重新思考您的设计,用Python思考,而不是用“private”和“getter”。)


编辑:

好像我误解了这个问题

标记有
@property
装饰符的函数将返回而不带括号调用它们(
spam.eggs
,而不是
spam.eggs()
),并且是“只读的”(您可以执行
bacon=spam.eggs
,但不能执行
spam.eggs=bacon

但我的其余评论仍然有效:

  • 只要有足够的决心,一切都是可以接近的
  • 使用下划线巧妙地要求人们不要访问该值
  • 如果您的getter属性返回一个可变对象,它在内部仍然可以更改(只有引用保持不变),例如
    eggs.list=[]
    将不起作用,但是
    eggs.list.append(“垃圾邮件”)
    将起作用
可以很容易地使用python内置实现只读字段:

class X:

    def __init__(self, val):
        self.foo = val

    def __setattr__(self, key, value):
        if not hasattr(self, key):  # only for first set
            super(X, self).__setattr__(key, value)
        else:
            raise ValueError


def main():
    x = X('bar')
    y = X('baz')

    assert x.foo == 'bar'
    assert y.foo == 'baz'

    # raises ValueError
    x.foo = 'Raise an error!'
如果要指定哪些字段是只读的

class X:

    readonly = ['foo']

    def __init__(self, val):
        self.foo = val

    def __setattr__(self, key, value):
        if key in self.readonly and not hasattr(self, key):
            super(X, self).__setattr__(key, value)
        else:
            raise ValueError


你在这里混淆了私有和只读。我希望它是公开的,但是只读的。即
a=obj.foo
有效,但
obj.foo=2
无效。编辑我的答案以解决只读部分。对我来说太早了,谢谢。我知道你指出的所有问题。但这不是答案。答案是:这是你怎么做的,否则这是不可能的。如果你认为这是一种不好的风格,公平地说,把它放在评论里。请给出一个真实的答案,否则我将不得不标记它。我解释了如何做类似于你想要的事情。而且总是有办法访问和更改“只读”变量。在我的编辑中,我解释了
@property
decorator是如何工作的(举例说明什么可以工作,什么不可以)。你还想要什么?你不能像在你的问题中那样“转换”,你必须以pythonical的方式编写代码并使用我给你的东西。你可以转换它,从某种意义上说,你可以删除字段(我知道这是可能的),并添加属性(也可能)。因为我想要的是,人们给我一个问题的答案,而不是其他问题的答案(不管是不是pythonic)。为了能有一个民间的讨论,谢谢。