- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在开发一个项目,其中有许多自定义类可以与用户系统上的各种数据集合进行交互。这些类仅具有作为面向用户的属性的properties
。其中一些属性是相当资源密集型的,因此我只想运行生成代码一次,并将返回值存储在磁盘上(即缓存它),以便在后续运行时更快地检索。就目前而言,这就是我实现这一目标的方式:
def stored_property(func):
"""This ``decorator`` adds on-disk functionality to the `property`
decorator. This decorator is also a Method Decorator.
Each key property of a class is stored in a settings JSON file with
a dictionary of property names and values (e.g. :class:`MyClass`
stores its properties in `my_class.json`).
"""
@property
@functools.wraps(func)
def func_wrapper(self):
print('running decorator...')
try:
var = self.properties[func.__name__]
if var:
# property already written to disk
return var
else:
# property written to disk as `null`
return func(self)
except AttributeError:
# `self.properties` does not yet exist
return func(self)
except KeyError:
# `self.properties` exists, but property is not a key
return func(self)
return func_wrapper
class MyClass(object):
def __init__(self, wf):
self.wf = wf
self.properties = self._properties()
def _properties(self):
# get name of class in underscore format
class_name = convert(self.__class__.__name__)
# this is a library used (in Alfred workflows) for interacted with data stored on disk
properties = self.wf.stored_data(class_name)
# if no file on disk, or one of the properties has a null value
if properties is None or None in properties.values():
# get names of all properties of this class
propnames = [k for (k, v) in self.__class__.__dict__.items()
if isinstance(v, property)]
properties = dict()
for prop in propnames:
# generate dictionary of property names and values
properties[prop] = getattr(self, prop)
# use the external library to save that dictionary to disk in JSON format
self.wf.store_data(class_name, properties,
serializer='json')
# return either the data read from file, or data generated in situ
return properties
#this decorator ensures that this generating code is only run if necessary
@stored_property
def only_property(self):
# some code to get data
return 'this is my property'
这段代码完全按照我的需要工作,但它仍然迫使我手动将 _properties(self)
方法添加到我需要此功能的每个类(目前,我有 3 个)。我想要的是一种将此功能“插入”到我喜欢的任何类中的方法。我认为类装饰器可以完成这项工作,但尽我所能,我不太明白如何解决它。
为了清楚起见(以防装饰器不是获得我想要的东西的最佳方式),我将尝试解释我所追求的整体功能。我想编写一个包含一些属性的类。这些属性的值是通过不同程度的复杂代码生成的(在一个实例中,我正在搜索某个应用程序的首选项文件,然后搜索 3 个不同的首选项(其中任何一个可能存在也可能不存在)并确定最佳的单个首选项这些偏好的结果)。我希望属性代码的主体仅包含用于查找数据的算法。但是,我不想每次访问该属性时都运行该算法代码。一旦我生成了一次值,我想将其写入磁盘,然后在所有后续调用中简单地读取该值。但是,我不希望每个值都写入自己的文件;我希望将单个类的所有属性的所有值的字典写入一个文件(因此,在上面的示例中,my_class.json
将包含一个带有一个键、值的 JSON 字典一对)。当直接访问该属性时,应首先检查该属性是否已存在于磁盘上的字典中。如果是,只需读取并返回该值即可。如果存在,但值为空,则尝试运行生成代码(即属性方法中实际编写的代码),看看现在是否可以找到它(如果没有,该方法将返回 None
并将再次写入文件)。如果字典存在并且该属性不是键(我当前的代码并没有真正使这成为可能,但安全总比抱歉好),运行生成代码并添加键、值对。如果字典不存在(即在类的第一次实例化时),则运行所有属性的所有生成代码并创建 JSON 文件。理想情况下,代码能够更新 JSON 文件中的一个属性,而无需重新运行所有生成代码(即再次运行 _properties()
)。
我知道这有点奇怪,但我需要速度、人类可读的内容和优雅的代码。我真的不必在我的目标上妥协。希望我想要的描述足够清楚。如果没有,请在评论中告诉我哪些地方没有意义,我会尽力澄清。但我确实认为类装饰器可能可以帮助我实现这一目标(本质上是通过将 _properties()
方法插入到任何类中,在实例化时运行它,并将其值映射到 properties
code> 类的属性)。
最佳答案
也许我遗漏了一些东西,但您的 _properties
方法似乎并不特定于给定类所具有的属性。我将它放在一个基类中,并让每个带有 @stored_property
方法的类都成为它的子类。那么您就不需要重复 _properties
方法。
class PropertyBase(object):
def __init__(self, wf):
self.wf = wf
self.properties = self._properties()
def _properties(self):
# As before...
class MyClass(PropertyBase):
@stored_property
def expensive_to_calculate(self):
# Calculate it here
如果由于某种原因你不能直接子类化PropertyBase
(也许你已经需要一个不同的基类),你可以使用mixin。如果失败,请让 _properties
接受实例/类和工作流对象,并在 __init__
中为每个类显式调用它。
关于python - 类装饰器自动更新磁盘上的属性字典?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26766319/
你能比较一下属性吗 我想禁用文本框“txtName”。有两种方式 使用javascript,txtName.disabled = true 使用 ASP.NET, 哪种方法更好,为什么? 最佳答案 我
Count 属性 返回一个集合或 Dictionary 对象包含的项目数。只读。 object.Count object 可以是“应用于”列表中列出的任何集合或对
CompareMode 属性 设置并返回在 Dictionary 对象中比较字符串关键字的比较模式。 object.CompareMode[ = compare] 参数
Column 属性 只读属性,返回 TextStream 文件中当前字符位置的列号。 object.Column object 通常是 TextStream 对象的名称。
AvailableSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。 object.AvailableSpace object 应为 Drive 
Attributes 属性 设置或返回文件或文件夹的属性。可读写或只读(与属性有关)。 object.Attributes [= newattributes] 参数 object
AtEndOfStream 属性 如果文件指针位于 TextStream 文件末,则返回 True;否则如果不为只读则返回 False。 object.A
AtEndOfLine 属性 TextStream 文件中,如果文件指针指向行末标记,就返回 True;否则如果不是只读则返回 False。 object.AtEn
RootFolder 属性 返回一个 Folder 对象,表示指定驱动器的根文件夹。只读。 object.RootFolder object 应为 Dr
Path 属性 返回指定文件、文件夹或驱动器的路径。 object.Path object 应为 File、Folder 或 Drive 对象的名称。 说明 对于驱动器,路径不包含根目录。
ParentFolder 属性 返回指定文件或文件夹的父文件夹。只读。 object.ParentFolder object 应为 File 或 Folder 对象的名称。 说明 以下代码
Name 属性 设置或返回指定的文件或文件夹的名称。可读写。 object.Name [= newname] 参数 object 必选项。应为 File 或&
Line 属性 只读属性,返回 TextStream 文件中的当前行号。 object.Line object 通常是 TextStream 对象的名称。 说明 文件刚
Key 属性 在 Dictionary 对象中设置 key。 object.Key(key) = newkey 参数 object 必选项。通常是 Dictionary 
Item 属性 设置或返回 Dictionary 对象中指定的 key 对应的 item,或返回集合中基于指定的 key 的&
IsRootFolder 属性 如果指定的文件夹是根文件夹,返回 True;否则返回 False。 object.IsRootFolder object 应为&n
IsReady 属性 如果指定的驱动器就绪,返回 True;否则返回 False。 object.IsReady object 应为 Drive&nbs
FreeSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。只读。 object.FreeSpace object 应为 Drive 对象的名称。
FileSystem 属性 返回指定的驱动器使用的文件系统的类型。 object.FileSystem object 应为 Drive 对象的名称。 说明 可
Files 属性 返回由指定文件夹中所有 File 对象(包括隐藏文件和系统文件)组成的 Files 集合。 object.Files object&n
我是一名优秀的程序员,十分优秀!