相关疑难解决方法(0)

Python类成员延迟初始化

我想知道初始化类成员的python方法是什么,但只有在访问它时才会访问它.我尝试了下面的代码并且它正在运行,但有什么比这简单吗?

class MyClass(object):

    _MY_DATA = None

    @staticmethod
    def _retrieve_my_data():
        my_data = ...  # costly database call
        return my_data

    @classmethod
    def get_my_data(cls):
        if cls._MY_DATA is None:
            cls._MY_DATA = MyClass._retrieve_my_data()
        return cls._MY_DATA
Run Code Online (Sandbox Code Playgroud)

python lazy-evaluation lazy-initialization

20
推荐指数
3
解决办法
1万
查看次数

如何pythonically有部分互斥的可选参数?

举一个简单的例子,取一个可以返回其属性的class 椭圆,例如面积A,周长C,长轴/短轴a/b,偏心率e等.为了得到它,显然必须提供其两个参数以获得所有其他参数,虽然作为一个特殊情况,只提供一个参数应该假设一个圆圈.三个或更多一致的参数应该产生警告但是有效,否则显然会引发异常.

所以有效Ellipses的一些例子是:

Ellipse(a=5, b=2)
Ellipse(A=3)
Ellipse(a=3, e=.1)
Ellipse(a=3, b=3, A=9*math.pi)  # note the consistency
Run Code Online (Sandbox Code Playgroud)

而无效的将是

Ellipse()
Ellipse(a=3, b=3, A=7)
Run Code Online (Sandbox Code Playgroud)

因此构造函数要么包含许多=None参数,

class Ellipse(object):
    def __init__(self, a=None, b=None, A=None, C=None, ...):
Run Code Online (Sandbox Code Playgroud)

或者,可能更明智,一个简单的**kwargs,可能添加提供a,b作为位置参数的选项,

class Ellipse(object):
    def __init__(self, a=None, b=None, **kwargs):
        kwargs.update({key: value
                       for key, value in (('a', a), ('b', b))
                       if value is not None})
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.但现在实际实现,即确定提供哪些参数,哪些参数不是,并根据它们确定所有其他参数,或在需要时检查一致性.

我的第一种方法是许多人的简单而乏味的组合

if 'a' in kwargs:
    a = kwargs['a'] …
Run Code Online (Sandbox Code Playgroud)

python arguments optional-parameters

12
推荐指数
5
解决办法
1375
查看次数

只计算一次属性并多次使用结果(不同的方法)

我试图多次使用类方法的结果,而不进行获得结果所需的繁重计算。

我看到以下选项。你认为哪些是正确的,或者更像 Pythonic?

每一种的优点和缺点是什么?

尝试/除外方法

class Test:
    def __init__(self, *args):
        # do stuff

    @property
    def new_method(self):
        try:
            return self._new_property
        except AttributeError:
            # do some heavy calculations
            return self._new_property
Run Code Online (Sandbox Code Playgroud)

lru_cache 方法

from functools import lru_cache

class Test:
    def __init__(self, *args):
        # do stuff

    @property
    @lru_cache()
    def new_method(self):
        # do some heavy calculations
        return self._new_property
Run Code Online (Sandbox Code Playgroud)

Django 的 cache_property 方法

from django.utils.functional import cached_property

class Test:
    def __init__(self, *args):
        # do stuff

    @cached_property
    def new_method(self):
        # do some heavy calculations
        return self._new_property
Run Code Online (Sandbox Code Playgroud)

python properties class-method

7
推荐指数
1
解决办法
1229
查看次数

使用try和except使用属性的正确方法

我有使用@property装饰器设置属性的类.它们使用try和except子句作为getter和setter.如果未设置attribute,它将从数据库获取数据并使用它来从其他类中实例化对象.我试图保持示例简短,但用于实例化属性对象的代码与每个属性略有不同.他们的共同点是尝试 - 开头时除外.

class SubClass(TopClass):

    @property
    def thing(self):
        try:
            return self._thing
        except AttributeError:
            # We don't have any thing yet
            pass
        thing = get_some_thing_from_db('thing')
        if not thing:
            raise AttributeError()
        self._thing = TheThing(thing)
        return self._thing

    @property
    def another_thing(self):
        try:
            return self._another_thing
        except AttributeError:
            # We don't have things like this yet
            pass
        another_thing = get_some_thing_from_db('another') 
        if not another_thing:
            raise AttributeError()
        self._another_thing = AnotherThing(another_thing)
        return self._another_thing

    ...etc...

    @property
    def one_more_thing(self):
        try:
            return self._one_more_thing
        except AttributeError:
            # We don't have this …
Run Code Online (Sandbox Code Playgroud)

python properties

4
推荐指数
1
解决办法
1919
查看次数

如何在功能上更新数据类?

我想复制冻结数据类的实例,仅更改一个字段(“功能更新”)。

这是我尝试过的

from dataclasses import dataclass, asdict    
@dataclass(frozen = True)    
class Pos:    
    start: int    
    end: int    
     
def adjust_start(pos: Pos, delta: int) -> Pos:    
   # TypeError: type object got multiple values for keyword argument 'start'    
   return Pos(**asdict(pos), start = pos.start + delta)    
     
adjust_start(Pos(1, 2), 4)   
Run Code Online (Sandbox Code Playgroud)

我正在寻找什么:

  • 有没有比dicts 转换更直接的方法?
  • 如何解决这个问题TypeError:如果有一种方法可以在功能上更新 kwargs,那么这是可行的。

在 Scala 中,案例类(Scala 数据类)的功能更新可以这样完成pos.copy(start = pos.start + delta)

python python-dataclasses

0
推荐指数
1
解决办法
4069
查看次数

让@property只运行一次

我有以下示例:

class A:
    value = None
    @property
    def value(self):
        if not value:
            result = <do some external call>
            self.value = result
        return self.value
Run Code Online (Sandbox Code Playgroud)

但是,由于我收到异常,因此无效:

AttributeError: can't set attribute
Run Code Online (Sandbox Code Playgroud)

这是有道理的,但做这样的事情的惯用方法是什么?我不只是想使用不同的名字.

python

-2
推荐指数
1
解决办法
128
查看次数