我如何在现有的python函数中添加一行代码

男生

我最近在阅读有关属性(即property装饰器)的文章,得出的结论是,我真的不喜欢它在python中的实现方式。好吧,我知道它不是语言本身的内部部分(例如,它没有像C#那样内置在语言中),但是我真的认为他们可以更好地实现它(即使只有装饰器)。我想对我认为应该实施的方式进行概念验证,但是我遇到了一点障碍(尽管没有什么可以克服的...)。

这就是我的想法:假设我们有一个Person带有属性name我定义属性的方式如下所示:

class Person():
    def __init__(self, name, age):
        self._name = name
        self._age = age

    @my_property
    def name(self):
        def getter(self):
            return self._name

        def setter(self, value):
            self._name = value

        def deleter(self):
             del self._name

        return getter, setter, deleter

我们的装饰器my_property定义如下:

def my_property(f):
    d = {g.__name__: g for g in f(None)}
    p = property(d.get('getter'), d.get('setter'), d.get('deleter'))
    return p

现在,这很好用,但是我真的很想通过允许用户不显式添加代码行来改进它return getter, setter, deleter相反,我希望装饰器将该行添加到f传递给它的函数中(在我们的示例中为name方法)。我猜我将不得不处理f(即f.__code__的代码对象,但是我无法弄清楚如何完成我想要的工作。

我关于属性外观的方式与属性的C#语法非常相似。我相信同一字段的getter,setter和deleteer应该在某些代码块中分组在一起(在我的情况下,我选择了一个函数定义),并且不要在(最多)3个单独的方法中遍及整个类(即使它们具有相同的名称,它们仍然在语法上是分隔开的。)...此外,我认为它是现在定义的方式-首先由property装饰器将getter声明为属性,然后使用getter的名称进行装饰设置器和删除器非常难看。但这只是我:)

更新

接受@User的答案后,我使用他的想法从包装方法的代码对象内部获取代码对象,重新实现了我的属性装饰器。这是我的新实现,仍然只是一个原型(我相信可以进一步改进)。我决定property用我的新装饰器(使用原始property装饰器)将内置装饰器遮盖起来,但是可以将其命名为任何内容...总的来说,我认为这很酷,我希望Python有一个property可以使用关键字定义属性,而不是使用方法定义或类定义(如@User在其答案中建议的那样)。

def property(f, property=property):
    from types import CodeType, FunctionType
    d = {code.co_name: FunctionType(code, f.__globals__)
         for code in f.__code__.co_consts
         if type(code) is CodeType}
    return property(d.get('getter'), d.get('setter'), d.get('deleter'), f.__doc__)


class Person():
    def __init__(self, name, age):
        self._name = name
        self._age = age

    @property
    def name():
        def getter(self):
            return self._name
        def setter(self, value):
            self._name = value
        def deleter(self):
            del self._name

>>> p1 = Person('Name', 25)
>>> p1.name
'Name'
>>> p1.name = "New Name"
>>> p1.name
'New Name'
用户

现在,您可以使其更漂亮:

>>> def dec(f):
    import types
    codes = []
    for code in f.__code__.co_consts:
        if isinstance(code, types.CodeType):
            codes.append(code)
    getter = types.FunctionType(codes[0], f.__globals__)
    setter = types.FunctionType(codes[1], f.__globals__)
    detter = types.FunctionType(codes[2], f.__globals__)
    return property(getter, setter, detter, f.__doc__)

>>> class X:
    @dec
    def f():
        def g(*args):
            print('get', args)
        def h(*args):
            print('set', args)
        def j(*args):
            print('del', args)


>>> X().f
get (<__main__.X object at 0x02DFD870>,)
>>> X().f = 1
set (<__main__.X object at 0x02E13750>, 1)
>>> del X().f
del (<__main__.X object at 0x02DFD870>,)

我对您的想法感兴趣。

但是也许使用类装饰器甚至更好

@dec
class attribute: 
     # ... functions

也许还有with语句:

with makeProperty:
     # ... functions

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

我如何使用javascript将一行输入框添加到现有的html表单中

如何在现有的csv文件中写入新行而不将其添加到最后一行?

如何在现有文本文件中的python中的一行中添加字符?

在现有的PHP Contact表单中添加另一行

如何改善我现有的GetOpenfile函数代码

如何在现有的手风琴搜索代码中添加搜索按钮?

如何在现有的JavaScript函数中添加JavaScript键盘快捷键?

我如何在一行代码中编写它?

如何在我现有的SQL Server 2012中添加分析服务?

如何使ReSharper不将我所有的.Bind语句添加到一行?

如何在现有的AspNetUsers表中添加列

如何在现有的PDF中添加注释

如何将一行代码注入现有函数?

如何在ionic 2中将一行文本添加到现有文件?

Python (selenium):如何在现有的 html 代码中搜索新的 html 文档

如何在第一行中显示我现有的列名,而不是“ _c0”,“ _ c1”,“ _ c2”,“ _ c3”,“ _ c4”?

Docker-如何在现有的Docker映像中添加新的python依赖项?

如何使用Python添加新行并将其填充到现有的Excel文件中

在Python的现有文件前添加一行

在现有 Excel 文件中添加一行并保存

在现有表中添加一行

如何在C#中调用将文本添加到现有代码中的函数?

如何在我现有的Android Studio项目中添加另一个项目?

从ajax提取行并追加到现有的最后一行中

如何在oracle中的现有自动增量表中插入一行?

在Visual Studio的每个函数中添加一行代码

有人可以向我解释函数中的一行代码吗

如何在所有函数中使用同一行代码?

有什么办法可以使我的函数在表中添加一行?