似乎有很多方法可以在Python中定义单例.Stack Overflow是否有共识?
我试图了解Python的描述符是什么以及它们对什么有用.但是,我没有成功.我理解它们是如何工作的,但这是我的疑惑.请考虑以下代码:
class Celsius(object):
def __init__(self, value=0.0):
self.value = float(value)
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
self.value = float(value)
class Temperature(object):
celsius = Celsius()
Run Code Online (Sandbox Code Playgroud)
为什么我需要描述符类?请使用此示例或您认为更好的示例进行说明.
什么是instance和owner这里?(in __get__).所以我的问题是,第三个参数的目的是什么?
我该怎么称呼/使用这个例子?
我有一个类有两个类方法(使用classmethod()函数)来获取和设置本质上是一个静态变量.我尝试使用property()函数,但它会导致错误.我能够在解释器中使用以下内容重现错误:
class Foo(object):
_var = 5
@classmethod
def getvar(cls):
return cls._var
@classmethod
def setvar(cls, value):
cls._var = value
var = property(getvar, setvar)
Run Code Online (Sandbox Code Playgroud)
我可以演示类方法,但它们不能作为属性:
>>> f = Foo()
>>> f.getvar()
5
>>> f.setvar(4)
>>> f.getvar()
4
>>> f.var
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: 'classmethod' object is not callable
>>> f.var=5
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: 'classmethod' object is not callable
Run Code Online (Sandbox Code Playgroud)
是否可以将property()函数与classmethod修饰函数一起使用?
基本上我想做这样的事情:
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>.有没有办法实现上述目标?
我创建了这样的Enum对象:
class Gender(Enum):
FEMALE = 'female'
MALE = 'male'
RANDOM = random.choice([FEMALE, MALE])
Run Code Online (Sandbox Code Playgroud)
我想每次都获得真正的随机值,但它不起作用:
>>> class Gender(Enum):
... MALE = 'male'
... FEMALE = 'female'
... RANDOM = choice([MALE, FEMALE])
...
>>> Gender.RANDOM
<Gender.MALE: 'male'>
>>> Gender.RANDOM
<Gender.MALE: 'male'>
>>> Gender.RANDOM
<Gender.MALE: 'male'>
>>> Gender.RANDOM
<Gender.MALE: 'male'>
Run Code Online (Sandbox Code Playgroud)
我也试过使用lambda,但看起来不太好,虽然它有效:
Gender.RANDOM()
Run Code Online (Sandbox Code Playgroud)
是否有其他方法可以每次获取随机值,而不使用lambda表达式?
我们使用这个枚举对象作为某个方法的参数的默认值,这就是为什么它应该是属性而不是函数,因为当我们使用Gender.FEMALE它时它不是一个函数,它是一个属性,也Gender.RANDOM应该是一个属性:
def full_name(gender=Gender.FEMALE):
...
def full_name(gender=Gender.RANDOM):
...
Run Code Online (Sandbox Code Playgroud) @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"\nRun 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
我制作了一个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-memberor 之类的东西unexpected-keyword-arg,仅仅是因为它认为Bar.foo是一种方法,而不是包装的classproperty对象。
我想为使用我的函数的任何代码禁用警告- 我绝对不能允许每次使用-wrapped 方法时都必须编写。我该怎么做?或者我应该改用不同的 linter?# pylint: disableclasspropertypylint
以下是由于上述原因生成的警告示例:
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-apprentice的努力中,如果我尝试使用类属性,我最近陷入了一些奇怪的(从我的角度来看)行为.我不是在抱怨,但是会感谢一些有用的评论来阐明这个问题.
为了将复杂的问题简化为一个更简洁的问题,我会像这样制定:
什么是"pythonic"方法来确保类属性在继承树中的行为更像静态变量?
在我看来,类属性的行为类似于具有多态特征的"读取时复制"默认值.只要我执行"只读"操作它就会保持"单例",但是很快,当我通过派生类或实例访问带有赋值的class-attribute时,它会变成一个新的引用,从而失去与继承了base-reference.
(它肯定有一些有趣的功能,但你必须理解它接受它,所以一些洞察力高度赞赏.)
class A(object):
classvar = 'A'
def setclassvar(self, value):
A.classvar = value
def __str__(self):
return "%s id(%s) " %(A.classvar, hex(id(A.classvar))[2:-1].upper())
class A1(A):
pass
class B(object):
classvar = 'B'
def setclassvar(self, value):
self.__class__.classvar = value
def __str__(self):
cvar = self.__class__.classvar
return "%s id(%s) " %(cvar, hex(id(cvar))[2:-1].upper())
class B1(B):
def setclassvar(self, value):
self.__class__.classvar = value
a, a1 = A(), A1()
a1.setclassvar('a')
print "new instance A: %s" %a
print "new instance A1: %s" %a
b, b1 = B(), B1() …Run Code Online (Sandbox Code Playgroud) 我试图在一个函数上同时使用@staticmethodand ,以便结果由and not返回。@propertybar()Foo.barFoo.bar()
但是,Foo.bar返回的是<property object at 0x107e9cb30>而不是预期的 string bar。
为什么@property装饰器不工作?
def do_work(str):
return str
class Foo:
@property
def foo(self):
return do_work('foo')
@staticmethod
@property
def bar():
return do_work('bar')
f = Foo()
print(f.foo) # foo
print(Foo.bar) # <property object at 0x107e9cb30>
Run Code Online (Sandbox Code Playgroud)
使用Python 3.7.4
How to define an attribute in a Python 3 enum class that is NOT an enum value?
class Color(Enum):
red = 0
blue = 1
violet = 2
foo = 'this is a regular attribute'
bar = 55 # this is also a regular attribute
Run Code Online (Sandbox Code Playgroud)
But this seems to fail for me. It seems that Color tries to include foo and bar as part of its enum values.
EDIT: Lest you think I'm not using Enum in a way that's …
python ×10
python-3.x ×3
class ×2
enums ×2
oop ×2
properties ×2
singleton ×2
descriptor ×1
lambda ×1
pylint ×1
random ×1