简体   繁体   English

function 如何像描述符一样工作?

[英]How Can a function act like a descriptor?

def typed_property(name, expected_type):
    storage_name = '_' + name

    @property
    def prop(self):
        return getattr(self, storage_name)

    @prop.setter
    def prop(self, value):
        if not isinstance(value, expected_type):
            raise TypeError('{} must be a {}'.format(name, expected_type))
        setattr(self, storage_name, value)
    return prop


class Person:
    name = typed_property('name', str)
    age = typed_property('age', int)
    def __init__(self, name, age):
        self.name = name
        self.age = age

Function typed_property() acts like a descriptor. Function typed_property() 就像一个描述符。 Why prop() is called when executing this code line (name = typed_property('name', str))?为什么执行此代码行时会调用 prop() (name = typed_property('name', str))?

I don't know what you mean by "descriptor".我不知道您所说的“描述符”是什么意思。 typed_property allows a property to call a function for additional processing. typed_property允许属性调用 function 进行额外处理。 prop() is not called when executing the line you mentioned.执行您提到的行时不会调用prop() It is called when executing self.name = name .它在执行self.name = name时被调用。 The @prop.setter makes it so the object can respond to property calls like that. @prop.setter使得 object 可以响应这样的属性调用。

When you call typed_property to set the value of the class properties name and age , you are really defining those to be methods to use to access the instance values self.name and self.age .当您调用typed_property来设置 class 属性nameage的值时,您实际上将它们定义为用于访问实例值self.nameself.age的方法。 This is the same as below omitting age for simplicity:为简单起见,这与以下省略年龄相同:

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

    @property
    def name(self):
        print("=== ACESSING")
        return self.name

    @name.setter
    def name(self, name):
        print("=== MUTATING")
        self.name = name

This marks the name(self) method as the accessor for self.name , and name(self, val) as the mutator.这将name(self)方法标记为self.name的访问器,并将name(self, val)标记为 mutator。 The mutator is called whenever you try to change (mutate) the value of its assigned property, in this case self.name .每当您尝试更改(变异)其分配属性的值时,都会调用 mutator,在本例中self.name This includes when you are calling it in the __init__ method.这包括您在__init__方法中调用它的时间。 However, using the class as defined above will result in an infinite recursion because I am calling the mutator from inside the mutator.但是,使用上面定义的 class 将导致无限递归,因为我是从 mutator 内部调用 mutator。 So "=== MUTATING" will be printed ending in a recursion error.所以 "=== MUTATING" 会以递归错误结尾。 So a small adjustment is needed:所以需要做一个小调整:

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

    @property
    def name(self):
        print("=== ACCESSING")
        return self._name

    @name.setter
    def name(self, val):
        print("=== MUTATING")
        self._name = val

Now that underlying property is name _name rather than name the mutator will set the value of _name rather than setting it for name and recur into itself infinitely.现在底层属性是 name _name而不是name ,mutator 将设置_name的值,而不是为name设置它并无限循环到自身。 For example, using the class as defined above:例如,使用上面定义的 class:

>>> p = Person("joshmeranda")
>>> p.name
=== ACCESSING
"joshmeranda"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使模型中的函数像字段一样起作用? - How to make a function inside a model act like a field? 如何使属性函数像数据库中的真实字段一样工作 - how to make a property function to act like a real field in the database 如何使 function 的参数像变量字符串方法一样 - How to make parameter of function act like variable string methods 如何将实例绑定描述符作为参考参数传递给 function? - How can I pass an instance binding descriptor as a reference argument to a function? kivy:如何使图像像按钮一样 - kivy: how to make an image act like a button 如何使四个子画面循环播放,使其表现得像GIF一样充当一个子画面? - How can I make four sprites looped so it behaves like a GIF act as ONE sprite? 如何在 Python 中实现 Act / Act 约定? - How can I realize Act / Act Convention in Python? 使绑定方法像函数一样运行的最pythonic方法是什么? - What is the most pythonic way to make a bound method act like a function? 如何在描述符外部访问存储在python描述符对象中的状态? - How can state stored in a python descriptor object be accessed outside the descriptor? var 可以像 python 中用 @property 装饰的 class 方法一样吗? - Can a var act like a class method decorated with @property in python?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM