在python中,我可以使用@classmethod
装饰器向类添加方法.是否有类似的装饰器向类中添加属性?我可以更好地展示我在说什么.
class Example(object):
the_I = 10
def __init__( self ):
self.an_i = 20
@property
def i( self ):
return self.an_i
def inc_i( self ):
self.an_i += 1
# is this even possible?
@classproperty
def I( cls ):
return cls.the_I
@classmethod
def inc_I( cls ):
cls.the_I += 1
e = Example()
assert e.i == 20
e.inc_i()
assert e.i == 21
assert Example.I == 10
Example.inc_I()
assert Example.I == 11
Run Code Online (Sandbox Code Playgroud)
我上面使用的语法是可能的还是需要更多的东西?
我想要类属性的原因是我可以延迟加载类属性,这似乎足够合理.
基本上我想做这样的事情:
class foo:
x = 4
@property
@classmethod
def number(cls):
return x
Run Code Online (Sandbox Code Playgroud)
然后我希望以下工作:
>>> foo.number
4
Run Code Online (Sandbox Code Playgroud)
不幸的是,上述方法无效.而不是给我4
它给我<property object at 0x101786c58>
.有没有办法实现上述目标?
在Python中使用抽象属性实现以下Scala代码的最短/最优雅的方法是什么?
abstract class Controller {
val path: String
}
Run Code Online (Sandbox Code Playgroud)
Controller
强制使用子类来定义Scala编译器的"路径".子类看起来像这样:
class MyController extends Controller {
override val path = "/home"
}
Run Code Online (Sandbox Code Playgroud) 说我有这样一个python Enum
类:
from enum import Enum
class Mood(Enum):
red = 0
green = 1
blue = 2
Run Code Online (Sandbox Code Playgroud)
是否有一种自然的方式来获得物品的总数Mood
?(像,而无需遍历它,或添加一个额外的n
项,或额外的n
classproperty
,等等).
enum
模块是否提供这样的功能?
@classmethod
在 Python 3.9 中,我们获得了链接和@property
合理创建类属性的能力。
class Foo:\n @property\n def instance_property(self):\n return "A regular property"\n\n @classmethod\n @property\n def class_property(cls):\n return "A class property"\n
Run Code Online (Sandbox Code Playgroud)\n这是通过与描述符协议进行适当的交互来实现的@classmethod
,这意味着一个人的前景不仅限于@property
阳光下的任何描述符。一切都很好,直到发现该实现导致了“许多下游问题”,并在 Python 3.11 中弃用。
我已经阅读了一些关于弃用的GitHub 讨论,并且不会在这里抱怨我所说的仓促撤回仓促设计。事实上,类属性是人们想要的合理的东西,并且可以在 Python 3.9/3.10 中使用,但现在不能。发行说明建议如下:
\n\n\n要 \xe2\x80\x9cpass-through\xe2\x80\x9d 类方法,请考虑使用 Python 3.10 中添加的 __wrapped__ 属性。
\n
如果说这样的句子本身极其无益,那就不会引起争议。描述符协议不是普通用户需要或想要遇到的东西,因此@classmethod
通过自定义实现与它们链接肯定是那些了解情况的人可以并且会花时间弄清楚如何在 3.11+ 中正确执行的操作。
但是对于那些不知道@property
除了允许他们删除括号的东西之外还有什么的人来说,如何在 Python 3.11+ 中定义类属性,特别是如何做得好?
python properties python-3.x python-decorators python-descriptors
我正在尝试找到扩展类变量的最佳方法.希望到目前为止我提出的方法的一个例子将清楚地说明这一点.
class A(object):
foo = ['thing', 'another thing']
class B(A):
foo = A.foo + ['stuff', 'more stuff']
Run Code Online (Sandbox Code Playgroud)
所以我试图让子类继承并扩展父类的变量.上面的方法有效,但似乎有些笨拙.我愿意接受任何建议,包括使用完全不同的方法完成类似的事情.
显然,如果需要,我可以继续使用这种方法,但如果有更好的方法我想找到它.
我想创建一个在抽象基类中声明的"类属性",然后在具体的实现类中重写,同时保持实现必须覆盖抽象基类的类属性的可爱断言.
虽然我看了一下这个问题,但我天真地尝试重新接受已接受的答案却没有用:
>>> import abc
>>> class ClassProperty(abc.abstractproperty):
... def __get__(self, cls, owner):
... return self.fget.__get__(None, owner)()
...
>>> class Base(object):
... __metaclass__ = abc.ABCMeta
... @ClassProperty
... def foo(cls):
... raise NotImplementedError
...
>>> class Impl(Base):
... @ClassProperty
... def foo(cls):
... return 5
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/2rs2ts/src/myproj/env/lib/python2.7/abc.py", line 94, in __new__
value = getattr(cls, name, None)
File "<stdin>", line 3, in __get__
TypeError: Error when calling …
Run Code Online (Sandbox Code Playgroud) 运行此代码:
import weakref
class A(object):
_instances = []
def __init__(self):
self._instances.append(weakref.ref(self))
@property
@classmethod
def instances(cls):
for inst_ref in cls._instances:
inst = inst_ref()
if inst is not None:
yield inst
foo = A()
bar = A()
for inst in A.instances:
print inst
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
Traceback (most recent call last):
File "test.py", line 18, in <module>
for inst in A.instances:
TypeError: 'property' object is not iterable
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚类方法的行为如何像属性(没有括号).
我制作了一个classproperty
描述符,每当我使用用它装饰的函数时,我都会收到多个pylint
检查错误。
这是一个带有示例装饰函数的示例类:
class Bar:
"""
Bar documentation.
"""
# pylint: disable=no-method-argument
@classproperty
def foo():
"""
Retrieve foo.
"""
return "foo"
Run Code Online (Sandbox Code Playgroud)
多亏了描述符,我可以调用Bar.foo
并获取返回的字符串foo。
不幸的是,每当我将这样的函数与稍微复杂的项目(例如返回对象实例的函数)一起使用时,就会pylint
开始抱怨诸如no-member
or 之类的东西unexpected-keyword-arg
,仅仅是因为它认为Bar.foo
是一种方法,而不是包装的classproperty
对象。
我想为使用我的函数的任何代码禁用警告- 我绝对不能允许每次使用-wrapped 方法时都必须编写。我该怎么做?或者我应该改用不同的 linter?# pylint: disable
classproperty
pylint
以下是由于上述原因生成的警告示例:
class Bar:
"""
Bar documentation.
"""
# pylint: disable=no-method-argument
@classproperty
def foo():
"""
Retrieve an object.
"""
return NotImplementedError("Argument")
print(Bar.foo.args)
Run Code Online (Sandbox Code Playgroud)
pylint
抱怨E1101: Method 'foo' …
python ×10
properties ×3
class ×2
oop ×2
python-3.x ×2
abc ×1
class-method ×1
enums ×1
metaclass ×1
pylint ×1
scala ×1
variables ×1