这个问题不是讨论单身人士设计模式是否可取,反模式,还是任何宗教战争,而是讨论如何以最蟒蛇的方式在Python中最好地实现这种模式.在这种情况下,我将"最pythonic"定义为表示它遵循"最小惊讶原则".
我有多个类可以成为单例(我的用例是记录器,但这并不重要).当我可以简单地继承或装饰时,我不希望在添加gumph的几个类中混乱.
最好的方法:
def singleton(class_):
instances = {}
def getinstance(*args, **kwargs):
if class_ not in instances:
instances[class_] = class_(*args, **kwargs)
return instances[class_]
return getinstance
@singleton
class MyClass(BaseClass):
pass
Run Code Online (Sandbox Code Playgroud)
优点
缺点
m = MyClass(); n = MyClass(); o = type(n)();那时m == n && m != o && n != oclass Singleton(object):
_instance = None
def __new__(class_, *args, **kwargs):
if not isinstance(class_._instance, class_):
class_._instance = object.__new__(class_, *args, **kwargs)
return class_._instance
class MyClass(Singleton, …Run Code Online (Sandbox Code Playgroud) 有没有办法在模块内部设置全局变量?当我尝试以最明显的方式执行此操作时,如下所示,Python解释器说该变量__DBNAME__不存在.
...
__DBNAME__ = None
def initDB(name):
if not __DBNAME__:
__DBNAME__ = name
else:
raise RuntimeError("Database name has already been set.")
...
Run Code Online (Sandbox Code Playgroud)
并在将模块导入另一个文件后
...
import mymodule
mymodule.initDB('mydb.sqlite')
...
Run Code Online (Sandbox Code Playgroud)
追溯是: __DBNAME__
有任何想法吗?我正在尝试使用模块来设置单例,根据这个人的建议.
在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)
我上面使用的语法是可能的还是需要更多的东西?
我想要类属性的原因是我可以延迟加载类属性,这似乎足够合理.
可能重复:
在Python中定义单例是否有简单,优雅的方法?
在Python中实现单例模式的最佳方法是什么?似乎不可能像通常使用Singleton模式那样声明构造函数是私有的还是受保护的......
为什么Borg模式比Singleton模式更好?
我问,因为我没有看到它们导致任何不同.
博格:
class Borg:
__shared_state = {}
# init internal state variables here
__register = {}
def __init__(self):
self.__dict__ = self.__shared_state
if not self.__register:
self._init_default_register()
Run Code Online (Sandbox Code Playgroud)
辛格尔顿:
class Singleton:
def __init__(self):
# init internal state variables here
self.__register = {}
self._init_default_register()
# singleton mechanics external to class, for example this in the module
Singleton = Singleton()
Run Code Online (Sandbox Code Playgroud)
我想在这里显示的是服务对象,无论是作为Borg还是Singleton实现,都有一个非常重要的内部状态(它提供了一些基于它的服务)(我的意思是它必须是有用的东西,它不是Singleton/Borg只是为了有趣).
而且这个州必须被引入.这里的Singleton实现更直接,因为我们将init视为全局状态的设置.我发现Borg对象必须查询其内部状态以查看它是否应该自行更新.
你拥有的内部状态越多,情况就越糟糕.例如,如果对象必须侦听应用程序的拆除信号以将其寄存器保存到磁盘,那么该注册也应该只执行一次,使用Singleton会更容易.
我的Python版本是2.6.
我想只执行一次测试setUp方法,因为我在那里做所有测试都需要的东西.
我的想法是创建一个布尔变量,在第一次执行后将设置为'true',然后禁用多次调用setup方法.
class mySelTest(unittest.TestCase):
setup_done = False
def setUp(self):
print str(self.setup_done)
if self.setup_done:
return
self.setup_done = True
print str(self.setup_done)
Run Code Online (Sandbox Code Playgroud)
输出:
False
True
--- Test 1 ---
False
True
--- Test 2 ---
Run Code Online (Sandbox Code Playgroud)
为什么这不起作用?我错过了什么吗?
我理解,在单例情况下,您可以执行以下操作:
spam == eggs
Run Code Online (Sandbox Code Playgroud)
如果spam和eggs是具有所有相同属性值的同一个类的实例,它将返回True.在Django模型中,这是很自然的,因为模型的两个独立实例将不会相同,除非它们具有相同的.pk值.
这样做的问题是,如果对实例的引用具有已经由中间件在某个地方更新并且尚未保存的属性,并且您正在尝试将其添加到另一个变量中,该变量持有对该实例的引用.同样的模型,它False当然会返回,因为它们对某些属性有不同的值.显然我不需要像单身人士这样的东西,但我想知道是否有一些官方的Djangonic(ha,一个新词)方法来检查这个,或者我是否应该只检查.pk值是否相同:
spam.pk == eggs.pk
Run Code Online (Sandbox Code Playgroud)
我很抱歉,如果这是浪费时间,但似乎可能有一种方法可以做到这一点,而我错过的一些事情,如果我找不到它,我会后悔的.
你应该忽略这个问题的第一部分,因为你不应该将单身人士与之比较==,而是与之比较is.单身者真的与这个问题无关.
假设我有两个不同的类实现
class ParentA:
def initialize(self):
pass
def some_event(self):
pass
def order(self, value):
# handle order in some way for Parent A
class ParentB:
def initialize(self):
pass
def some_event(self):
pass
def order(self, value):
# handle order in another for Parent B
Run Code Online (Sandbox Code Playgroud)
我怎样才能动态地让一些第三类继承ParentA或ParentB基于这样的东西?
class MyCode:
def initialize(self):
self.initial_value = 1
def some_event(self):
# handle event
order(self.initial_value)
# let MyCode inherit from ParentA and run
run(my_code, ParentA)
Run Code Online (Sandbox Code Playgroud) 我目前正在学习Python,我必须从事Python 2.7项目.
在模块本身的功能中访问"模块范围"变量对我来说有点混乱,我没有成功找到令人满意的方式.
到目前为止我的尝试:
方式1:
my_module.py
my_global_var = None
def my_func():
global my_global_var
my_global_var = 'something_else'
Run Code Online (Sandbox Code Playgroud)
在这里,我认为混淆本地和"模块范围"变量可能非常容易.
方式2:
my_module.py
import my_module
my_global_var = None
def my_func():
my_module.my_global_var = 'something_else'
Run Code Online (Sandbox Code Playgroud)
在这里,必要时,"my_module"的名称不能像"方式1"那样容易地改变.另外,将模块导入自身听起来很奇怪.
你会推荐什么?或者你会推荐别的吗?谢谢.
python ×8
singleton ×5
module ×2
scope ×2
variables ×2
base-class ×1
class-method ×1
coding-style ×1
decorator ×1
django ×1
go ×1
inheritance ×1
metaclass ×1
properties ×1
unit-testing ×1