我正在尝试Flag使用抽象方法创建一个抽象枚举(实际上)。我的最终目标是能够根据我定义的基本枚举创建复合枚举的字符串表示形式。我可以在不使类抽象的情况下获得此功能。
这是基本Flag类和示例实现:
from enum import auto, Flag
class TranslateableFlag(Flag):
@classmethod
def base(cls):
pass
def translate(self):
base = self.base()
if self in base:
return base[self]
else:
ret = []
for basic in base:
if basic in self:
ret.append(base[basic])
return " | ".join(ret)
class Students(TranslateableFlag):
ALICE = auto()
BOB = auto()
CHARLIE = auto()
ALL = ALICE | BOB | CHARLIE
@classmethod
def base(cls):
return {Students.ALICE: "Alice", Students.BOB: "Bob",
Students.CHARLIE: "Charlie"}
Run Code Online (Sandbox Code Playgroud)
一个示例用法是:
((Students.ALICE | Students.BOB).translate())
[Out]: 'Alice | …Run Code Online (Sandbox Code Playgroud) 有没有办法在同一个python会话中加载模块两次?
用一个例子填写这个问题:这是一个模块:
Mod.py
x = 0
Run Code Online (Sandbox Code Playgroud)
现在我想导入该模块两次,比如创建一个类的两个实例,实际上有两个副本x.
要回答评论中的问题,"为什么有人会想要这样做,如果他们只能创建一个带有x变量的类":
你是对的,但是存在一些必须重写的大量源代码,并且加载一个模块两次将是一个快速修复^^.
我有一堂这样的课:
from __future__ import annotations
import os
from dataclasses import dataclass
@dataclass(frozen=True)
class Config:
name: str
age: str
@staticmethod
def init() -> Config:
return Config(
name=...
age=...
)
Run Code Online (Sandbox Code Playgroud)
我想确保 init 方法始终返回相同的Config.
我可以通过这样做来实现这一目标:
@dataclass(frozen=True)
class Config:
name: str
age: str
@staticmethod
def init() -> Config:
if not _private_instance:
global _private_instance = Config(
name=...
age=...
)
return _private_instance
_private_instance: Optional[Config] = None
But I am wondering if there is a more Pythonic way of doing this. Thanks
Run Code Online (Sandbox Code Playgroud) 在我作为一个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) 我是python编程的新手,我有一个类,对于这个类,我创建了一个对象(obj1).i不想创建除此对象之外的其他对象,如果有任何体想要为此类创建一个应该引用的对象到第一个对象(而不是再创建一个对象).如何做到这一点?请参考以下代码?
Run Code Online (Sandbox Code Playgroud)class MyClass: def __init__(self): pass obj1=MyClass()//create object obj2=MyClass()//avoid creation and refer obj2 to obj1 obj3=MyClass()//avoid creation and refer obj3 to obj1
最近我读了一篇关于如何在Python中创建单例的有趣讨论.其中一个解决方案是一个棘手的装饰器,在其代码中定义一个类作为装饰类的替代:
def singleton(class_):
class class_w(class_):
_instance = None
def __new__(class2, *args, **kwargs):
if class_w._instance is None:
class_w._instance = super(class_w, class2).__new__(class2, *args, **kwargs)
class_w._instance._sealed = False
return class_w._instance
def __init__(self, *args, **kwargs):
if self._sealed:
return
super(class_w, self).__init__(*args, **kwargs)
self._sealed = True
class_w.__name__ = class_.__name__
return class_w
@singleton
class MyClass(object):
def __init__(self, text):
print text
@classmethod
def name(class_):
print class_.__name__
x = MyClass(111)
x.name()
y = MyClass(222)
print id(x) == id(y)
Run Code Online (Sandbox Code Playgroud)
输出是:
111 # the __init__ is called …Run Code Online (Sandbox Code Playgroud) 想象一下,有一个框架提供了一个方法logutils.set_up(),根据一些配置设置日志记录.
应尽早设置日志记录,因为导入库期间发出的警告不应丢失.
由于旧的way(if __name__=='__main__':)看起来很丑,我们使用console_script入口点来注册该main()方法.
# foo/daily_report.py
from framework import logutils
logutils.set_up()
def main():
...
Run Code Online (Sandbox Code Playgroud)
我的问题是logutils.set_up()可能会被调用两次:
想象一下,有一个第二个控制台脚本调用logutils.set_up()和imports daily_report.py.
我可以更改框架代码并set_up()在第二次调用中什么也不做logutils.set_up(),但这感觉很笨拙.我想避免它.
我怎么能确定logutils.set_up()只执行一次?
警告:以下问题要求提供有关不良做法和脏代码的信息。建议开发商酌情决定。
注意:这与在 Python 中创建单例问题不同,因为我们想要解决酸洗和复制以及正常的对象创建问题。
目标:我想创建一个NoParam模拟 行为的值(称为 )None。具体来说,我希望 的任何实例都NoParamType具有相同的值——即具有相同的值id——以便is运算符始终在这些值中的两个值之间返回True。
原因:我有保存参数值的配置类。其中一些参数可以None作为有效类型。但是,如果未指定类型,我希望这些参数采用特定的默认值。因此我需要一些哨兵来is not None指定未指定任何参数。该哨兵必须是永远不能用作有效参数值的东西。我更愿意为这个哨兵使用特殊类型,而不是使用一些不太可能使用的字符串。
例如:
def add_param(name, value=NoParam):
if value is NoParam:
# do some something
else:
# do something else
Run Code Online (Sandbox Code Playgroud)
但我们不必太担心原因。让我们重点关注如何做。
到目前为止我所拥有的:
我可以很容易地实现大部分这种行为。我创建了一个名为 的特殊模块util_const.py。它包含一个创建 NoParamType 的类,然后创建该类的单例实例。
class _NoParamType(object):
def __init__(self):
pass
NoParam = _NoParamType()
Run Code Online (Sandbox Code Playgroud)
我只是假设永远不会创建此类的第二个实例。每当我想使用值时,我import util_const就会使用util_const.NoParam.
这对于大多数情况都很有效。然而,我刚刚遇到了一个NoParam值被设置为对象值的情况。使用深度复制该对象copy.deepcopy,因此创建了第二个 NoParam 实例。
我通过定义__copy__和__deepcopy__方法找到了一个非常简单的解决方法
class …Run Code Online (Sandbox Code Playgroud) 目标是通过从 和 派生的元类创建一个抽象枚举abc.ABCMeta类enum.EnumMeta。例如:
import abc
import enum
class ABCEnumMeta(abc.ABCMeta, enum.EnumMeta):
pass
class A(abc.ABC):
@abc.abstractmethod
def foo(self):
pass
class B(A, enum.IntEnum, metaclass=ABCEnumMeta):
X = 1
class C(A):
pass
Run Code Online (Sandbox Code Playgroud)
现在,在 Python3.7 上,该代码将被正确解释(在 3.6.x 和可能更低的版本上,不会出现错误)。事实上,一切看起来都很棒,我们的 MRO 展示B源自 A和IntEnum。
>>> B.__mro__
(<enum 'B'>, __main__.A, abc.ABC, <enum 'IntEnum'>, int, <enum 'Enum'>, object)
Run Code Online (Sandbox Code Playgroud)
然而,即使B.foo尚未定义,我们仍然可以B毫无问题地实例化并调用foo().
>>> B.X
<B.X: 1>
>>> B(1)
<B.X: 1>
>>> B(1).foo()
Run Code Online (Sandbox Code Playgroud)
这看起来相当奇怪,因为即使我使用自定义元类,从 ABCMeta 派生的任何其他类都无法实例化。
>>> class …Run Code Online (Sandbox Code Playgroud) 我找到了一种优雅的方法来装饰Python类来实现它singleton.该类只能生成一个对象.每次Instance()调用都返回相同的对象:
class Singleton:
"""
A non-thread-safe helper class to ease implementing singletons.
This should be used as a decorator -- not a metaclass -- to the
class that should be a singleton.
The decorated class can define one `__init__` function that
takes only the `self` argument. Also, the decorated class cannot be
inherited from. Other than that, there are no restrictions that apply
to the decorated class.
To get the singleton instance, use the …Run Code Online (Sandbox Code Playgroud)