Class foo有一个酒吧.条形码在访问之前不会加载.进一步访问bar应该不会产生任何开销.
class Foo(object):
def get_bar(self):
print "initializing"
self.bar = "12345"
self.get_bar = self._get_bar
return self.bar
def _get_bar(self):
print "accessing"
return self.bar
Run Code Online (Sandbox Code Playgroud)
是否可以使用属性或更好的属性来执行此类操作,而不是使用getter方法?
目标是在所有后续访问中没有开销的延迟加载......
我有一个测试框架,需要使用以下类模式定义测试用例:
class TestBase:
def __init__(self, params):
self.name = str(self.__class__)
print('initializing test: {} with params: {}'.format(self.name, params))
class TestCase1(TestBase):
def run(self):
print('running test: ' + self.name)
Run Code Online (Sandbox Code Playgroud)
当我创建并运行测试时,我得到以下内容:
>>> test1 = TestCase1('test 1 params')
initializing test: <class '__main__.TestCase1'> with params: test 1 params
>>> test1.run()
running test: <class '__main__.TestCase1'>
Run Code Online (Sandbox Code Playgroud)
测试框架搜索并加载TestCase它可以找到的所有类,实例化每个类,然后run为每个测试调用该方法.
load_test(TestCase1(test_params1))
load_test(TestCase2(test_params2))
...
load_test(TestCaseN(test_params3))
...
for test in loaded_tests:
test.run()
Run Code Online (Sandbox Code Playgroud)
但是,我现在有一些测试用例,在__init__调用方法之前我不希望调用该run方法,但是我几乎无法控制框架结构或方法.如何在__init__ 不重新定义__init__或run方法的情况下延迟呼叫?
推测这起源于XY问题是正确的.一段时间,当我维护测试框架时,一位同事问我这个问题.我进一步询问了他真正想要实现的目标,我们想出了一个更简单的解决方法,不涉及更改框架或引入元类等. …
我想创建一个像属性一样工作的装饰器,只调用一次装饰函数,后续调用总是返回第一次调用的结果.一个例子:
def SomeClass(object):
@LazilyInitializedProperty
def foo(self):
print "Now initializing"
return 5
>>> x = SomeClass()
>>> x.foo
Now initializing
5
>>> x.foo
5
Run Code Online (Sandbox Code Playgroud)
我的想法是为此编写一个自定义装饰器.所以我开始了,这就是我走了多远:
class LazilyInitializedProperty(object):
def __init__(self, function):
self._function = function
def __set__(self, obj, value):
raise AttributeError("This property is read-only")
def __get__(self, obj, type):
# problem: where to store the value once we have calculated it?
Run Code Online (Sandbox Code Playgroud)
如您所见,我不知道存储缓存值的位置.最简单的解决方案似乎只是维护字典,但我想知道是否有更优雅的解决方案.
编辑很抱歉,我忘了提到我希望该房产是只读的.
我想要实现以下目标:
class A:
username = None
username = get_username()
def get_username(self):
if username is None:
try:
uname = os.environ["USER"]
except:
printf("Couldn't find a user name")
return uname
return username
Run Code Online (Sandbox Code Playgroud)
不知道如何实现这一目标.我确定我错过了一些"自我".前缀,但这是我第一次使用python和静态成员.
从某种意义上说,我想要一个具有一些成员和函数的类来计算这些成员的值,但我不想重新计算.我也希望这些是静态函数和数据成员.
问题是该行"username = get_username()"尚未定义该函数.如果我在功能之后输入用户名,那么它就不是
是否可以在类上具有静态属性,该属性将作为一次性计算.我们的想法是能够这样做:
class Foo:
static_prop = Foo.one_off_static_method()
@staticmethod
def one_off_static_method():
return 'bar'
Run Code Online (Sandbox Code Playgroud)
我也想过使用__new__它.
Class Foo:
def __new__(cls):
cls.static_prop = ... do everything here
Run Code Online (Sandbox Code Playgroud)
虽然不确定这个含义.
有时我喜欢为一个对象编写getter属性,这样第一次调用它们时,繁重的工作就会完成一次,并且该值会被保存并在将来的调用中返回.在objective-c中,我将使用ivar或静态变量来保存此值.就像是:
- (id)foo
{
if ( _foo == nil )
{
_foo = // hard work to figure out foo
}
return _foo
}
Run Code Online (Sandbox Code Playgroud)
这种相同的模式在Python中是否能够很好地运行,或者有更多可接受的方式吗?到目前为止我基本上都是一样的.我不喜欢我的解决方案是我的对象混淆了值和这些值的getter:
def foo(self):
if not hasattr(self, "mFoo":
self.mFoo = # heavy lifting to compute foo
return self.mFoo
Run Code Online (Sandbox Code Playgroud) 我有一个用Python编写的程序,它执行以下操作:
用户输入文件夹的名称.在该文件夹中有8-15个.dat文件,具有不同的扩展名.
程序打开这些dat文件,将它们输入到SQL数据库中,然后允许用户选择对数据库所做的不同更改.然后将数据库导出回.dat文件.可以执行大约5-10种不同的操作.
我计划设计的方法是为每组文件创建一个标准类.用户将输入文件夹的名称,并且将创建具有某些属性(文件名,文件字典,文件版本(有不同版本)等)的对象.确定这些属性需要打开其中一些文件,读取文件名等.
这个行动应该在__init__方法中进行吗?或者,是否应该在方法中调用的不同实例方法中执行此操作__init__?或者这些方法应该在其他地方,只有在程序中的其他地方需要属性时才能调用它们?
我已经用Java编写了这个程序.我有一个构造函数,它调用类中的其他方法来设置对象的属性.但我想知道Python中的标准做法是什么.
我有一个django模型,需要参考自定义用户模型进行一些处理。
在类加载时,我无法使用此模型的类,因为类的加载顺序是未知的。
因此,我需要在运行时添加一些类属性,此刻,我需要将它们添加到中__init__或__new__类似的地方:
def __new__(cls, *args, **kwargs):
# hack to avoid INSTALLED_APPS initialization conflicts.
# get_user_model() can't be called from this module at class loading time,
# so some class attributes must be added later.
# Metaclasses could me more appropiate but I don't want to override
# dango's metaclasses.
if not hasattr(cls, '_reverse_field_name_to_user'):
cls._find_reverse_field_name_to_user()
return Group.__new__(cls, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
它可以工作,但是看起来很可怕,所以我考虑过@lazyclassproperty对这些属性使用类似的东西。
我已经发现了几个@classproperty和@lazyproperty装修而不是一个两个,我不知道如何写一个自己。
问题:如何编码这样的装饰器?或建议另一种更清洁的方法替代我目前的愚蠢实施。