如何在Python中定义作为类实例的类字段?

时间:2019-06-23 17:51:17

标签: c# python metaprogramming

我想在类的名称空间中获取特定的类实例。在C#中,它看起来像这样:

public struct Foo
{
    public readonly static Bar = new Foo();
}

我唯一的想法是在类定义(monkeypatch)之后立即分配一个实例:

class Foo:
    def __init__(self, spam):
        self.spam = spam
Foo.bar = Foo(42)

但是我想在类定义中提供实例,像这样:

class Foo:
    ...
    bar = Foo(42)

和这样的界面:

from foo import Foo
bar = Foo.bar

定义的最后一行给出了语法错误,因为尚未定义Foo。除了Monkeypatching类之外,还有什么方法可以克服这种限制?

4 个答案:

答案 0 :(得分:3)

可以通过自定义描述符对象(doc)实现所请求的功能:

class static_property:
    def __init__(self, getter):
        self.__getter = getter

    def __get__(self, obj, objtype):
        return self.__getter(objtype)

    @staticmethod
    def __call__(getter_fn):
        return static_property(getter_fn)

class A:
    _bar = None

    def __init__(self, spam):
        self.spam = spam

    @static_property
    def bar(cls):
        if cls._bar is None:
            cls._bar = A(10)
        return cls._bar

print('A.bar={} A.bar.spam={}'.format(A.bar, A.bar.spam))

a = A(20)
print('a.bar={} a.bar.spam={} a.spam={}'.format(a.bar, a.bar.spam, a.spam))

打印:

A.bar=<__main__.A object at 0x7f0ab5e41eb8> A.bar.spam=10
a.bar=<__main__.A object at 0x7f0ab5e41eb8> a.bar.spam=10 a.spam=20

答案 1 :(得分:0)

要在课堂上工作,您需要File file = new File(Environment.getExternalStorageDirectory() + "/_audio_record.3gp"); try { byte[] bytes = FileUtils.readFileToByteArray(file); String encoded = Base64.encodeToString(bytes, 0); Toast.makeText(getApplicationContext(),encoded,Toast.LENGTH_LONG) .show(); } catch (IOException e) { e.printStackTrace(); } 装饰器。

@classmethod

答案 2 :(得分:0)

您可以将其转换为可外部调用的方法,例如:-

class Foo:
    def __init__(self,data):
        self.data = data

    def update(self,value):
        self.bar = Foo(value)
        self.show()

    def show(self):
        print(self.bar.data,"Updated Successfully")


if __name__ == "__main__":
    node = Foo(None)

    node.update(10)
    node.update(20)
    node.update("Hello World")


此代码的输出将类似于:-

10 Updated Successfully
20 Updated Successfully
Hello World Updated Successfully

您可以通过:-

直接使用bar(新实例)
#node.bar.data
print(node.bar.data)

输出将是最后更新的值,即:-

Hello World

答案 3 :(得分:0)

如果您要为此使用元类,则可以使用following。我确实不知道您为什么要实现这一目标,或者我提出的方法是否很好,但是仍然行之有效。

class Meta(type):
    def __new__(cls, name, bases, dct):
        print(cls,name, bases, dct)
        x = super(Meta, cls).__new__(cls, name, bases, dct)
        x.bar = x(46) //create the bar for the Foo
        return x




class Foo:
    __metaclass__ = Meta
    def __init__(self, spam):
        self.spam = spam

这是在为类创建对象时简单地为bar创建一个Foo命名属性。我猜代码是不言自明的