Property、attributey、field有啥区别?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Property、attributey、field有啥区别?相关的知识,希望对你有一定的参考价值。

Property、attribute、characteristic、field有什么区别?

1、Property 你可以理解为属性,属性基本是为了在类的外部对私有变量的值进行读/取。

2、attribute 这个你可以理解为 特性,一般写在类头上面,表示为这个类添加了某些特性。
以下代码表示 AAA 可以被序列化。
[Serializable]
public class AAA : Base

3、characteristic 不太清楚具体是什么,翻译过来的是 特征、特性。

4、field 翻译过来是 域 的意思
域这个词不太好讲,我一般将它理解为访问界限或者区域。

举个最简单的例子

public void TEST()

int a = 0;

//a 的作用域到此结束。

int a = 1;//这样会报错

=========================
int a = 0;//下面都是a的作用域
public void TEST()

a = 1;//这样不会报错
参考技术A 1.Property:
属性是这样的成员:它们提供灵活的机制来读取、编写或计算私有字段的值。可以像使用公共数据成员一样使用属性,但实际上它们是称作“访问器”的特殊方法。这使得可以轻松访问数据,此外还有助于提高方法的安全性和灵活性。
例如,为类TimePeriod定义属性Hours:
class TimePeriod

private double seconds;

public double Hours

get return seconds / 3600;
set seconds = value * 3600;



2.Attribute:
属性提供功能强大的方法以将声明信息与 C# 代码(类型、方法、属性等)相关联。属性与程序实体关联后,即可在运行时使用名为“反射”的技术查询属性。有关更多信息,请参见反射(C# 编程指南)。

属性以两种形式出现:

一种是在公共语言运行库 (CLR) 中定义的属性。
另一种是可以创建的用于向代码中添加附加信息的自定义属性。此信息可在以后以编程方式检索

例,属性 TypeAttributes.Serializable 用来将特定特性应用于类:
[System.Serializable]
public class SampleClass

// Objects of this type can be serialized.


characteristic和field在C#中无此概念

如何在 django 中使 @cached_property 无效

【中文标题】如何在 django 中使 @cached_property 无效【英文标题】:How do I invalidate @cached_property in django 【发布时间】:2014-06-22 18:18:23 【问题描述】:

我目前在模型类上使用@cached_property,我想在保存时将其删除,以便在下次调用时重新填充。我该怎么做呢? 示例:

class Amodel():
    #...model_fields....

    @cached_property
    def db_connection(self):
        #get some thing in the db and cache here


instance = Amodel.objects.get(id=1)
variable = instance.db_connection

Amodel.objects.select_for_update().filter(id=1).update(#some variable)
#invalidate instance.db_connection
#new_variable = instance.db_connection

谢谢

【问题讨论】:

【参考方案1】:

只需删除它作为文档says。这将导致在下次访问时重新计算。

class SomeClass(object):
    
    @cached_property
    def expensive_property(self):
         return datetime.now()

obj = SomeClass()
print obj.expensive_property
print obj.expensive_property # outputs the same value as before
del obj.expensive_property
print obj.expensive_property # outputs new value

对于 Python 3,del 的用法相同。下面是一个 try/except 块的示例。

try:
    del obj.expensive_property 
except AttributeError:
    pass 

【讨论】:

请注意,如果该属性尚未被访问/缓存,这将生成一个 AttributeError。在这种情况下,尝试将其包装起来,但 AttributeError 除外。 好消息@dalore; django 开发人员的糟糕样板:( 请注意,如果您在班级内无效,您将使用del self.__dict__['expensive_property']...除非有我不知道的非dunder方式。 @cached_property 绝对不是有点糟糕的样板!这是对实例字典和描述符协议之间相互作用的简洁使用。如果你在属性被调用/缓存之前尝试delattr,那么它会抛出AttributeError,这是完全有道理的,这是标准的python行为。这很有意义,因为cached_property 精确地将属性 写入 实例字典,而不是在第一次运行后调用自身。花点时间研究一下,你会发现这是一段既甜美又经济的代码。 链接改为docs.djangoproject.com/en/3.0/ref/utils/…;无法编辑。【参考方案2】:

我创建了一个 Django 模型 mixin,它在调用 model.refresh_from_db() 时使模型上的所有 @cached_property 属性无效。您也可以使用 model.invalidate_cached_properties() 使缓存的属性无效。

from django.utils.functional import cached_property


class RefreshFromDbInvalidatesCachedPropertiesMixin():

    def refresh_from_db(self, *args, **kwargs):
        self.invalidate_cached_properties()
        return super().refresh_from_db(*args, **kwargs)

    def invalidate_cached_properties(self):
        for key, value in self.__class__.__dict__.items():
            if isinstance(value, cached_property):
                self.__dict__.pop(key, None)

https://gitlab.com/snippets/1747035

受Thomas Baden 的回答启发。

【讨论】:

如果您使用from functools import cached_property,它将无法正常工作。所以我建议,检查多个字段类型:if isinstance(value, (cached_property, django_cached_property)):【参考方案3】:

由于正在进行的开发而进行了大量编辑...现在支持给定 cached_property 的多个标签。

我遇到了类似的问题,其中我有一组相关的 cached_property 对象,它们都需要同时失效。我以这种方式解决了它:

    扩展cached_property 以接受标签值并包含装饰器类方法:

    def __init__(self, func, *tags):
        self.func = func
        self.tags = frozenset(tags)
    
    @classmethod
    def tag(cls *tags):
        return lambda f: cls(f, *tags)
    

    在我的其他对象中,使用我的新 cached_property.tag 装饰器类方法来定义标记的 cached_property 方法:

    @cached_property.tag("foo_group")
    def foo(self):
        return "foo"
    

    在我使用新装饰器的对象上,编写一个方法,通过遍历实例化对象类的__dict__,使所有带有命名标记的cached_property 值无效。这可以防止意外调用所有 cached_property 方法:

    def invalidate(self, tag):
        for key, value in self.__class__.__dict__.items():
            if isinstance(value, cached_property) and tag in value.tags:
                self.__dict__.pop(key, None)
    

现在,为了使无效,我只需调用myobject.invalidate("foo_group")

【讨论】:

【参考方案4】:

如果你不想使用tryexcept,而且写的行数也少,可以使用:

if (hasattr(obj, "expensive_property")):
    delattr(obj, "expensive_property")

或者:

if (hasattr(obj, "expensive_property")):
    del obj.expensive_property

会删除缓存的属性,下次访问时会重新计算。

【讨论】:

以上是关于Property、attributey、field有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

C#面向对象字段(Field)和属性(Property)的区别

MS 访问控制 Property.Type 没有意义

多重赋值(字段 = 属性 = 值)

Property or field ‘xxx‘ cannot be found on object of type ‘Boolean‘ - maybe not public or not valid?

Grails Fields插件显示的自定义字段

Accessors桥面运用