Python中的C#样式属性

0 投票
1 回答
1013 浏览
提问于 2025-04-15 22:44

我想在Python中定义属性,方式类似于C#,可以有嵌套的获取和设置定义。
这是我目前做到的:

#### definition ####    

def Prop(fcn):
    f = fcn()
    return property(f['get'], f['set'])


#### test ####

class Example(object):

    @Prop
    def myattr():

        def get(self):
            return self._value

        def set(self, value):
            self._value = value

        return locals()  #  <- how to get rid of this?

e = Example()
e.myattr = 'somevalue' 
print e.myattr


问题是,这样做仍然需要定义为'return locals()'。
有没有办法去掉这个呢?
也许可以用嵌套的装饰器?

1 个回答

2

你可以用 return get, set 这种更优雅的方式来处理你的 Prop

def Prop(fcn):
    g, s = fcn()
    return property(g, s)

不过,想要在被装饰的函数中不使用任何 return 语句是没有什么“干净”的方法的。一个包含内部 def 语句的函数,和一个包含内部赋值的函数一样,实际上在被调用之前并不会执行这些语句——这些赋值和 def 语句所要创建和绑定的对象和名称,字面上是找不到的。

一旦函数被调用,这些名称和对象就变成了函数内部的局部变量——所以,如果没有外部的引用,它们就会消失……而且,确保局部名称有外部引用的优雅方法,除了以某种形式 return 它们之外,真的没有了。

问题在于你坚持想要装饰一个 函数 对象(按设计,它会把局部名称保留得很私密)。如果你同意用正确的关键字来替代 def,那么一切都会顺利进行——这个正确的关键字是 class。(注意,你需要 Python 2.6 或更高版本来实现这一点)……:

def Prop(cls):
    f = cls.__dict__
    return property(f['get'], f['set'])


#### test ####

class Example(object):

    @Prop
    class myattr():

        def get(self):
            print 'getting', self._value
            return self._value

        def set(self, value):
            print 'setting', value
            self._value = value


e = Example()
e.myattr = 'somevalue' 
print e.myattr

与函数相比,类在“内部”内容上要透明得多,所以一个 class 装饰器可以轻松实现你想要的效果。注意那些小的变化:用 __dict__ 来访问被装饰类的字典,在被装饰的对象中将 def 替换为 class,并去掉你不喜欢的 return 语句。

撰写回答