相关疑难解决方法(0)

在Python中创建单例

这个问题不是讨论单身人士设计模式是否可取,反模式,还是任何宗教战争,而是讨论如何以最蟒蛇的方式在Python中最好地实现这种模式.在这种情况下,我将"最pythonic"定义为表示它遵循"最小惊讶原则".

我有多个类可以成为单例(我的用例是记录器,但这并不重要).当我可以简单地继承或装饰时,我不希望在添加gumph的几个类中混乱.

最好的方法:


方法1:装饰者

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)

优点

  • 装饰器的添加方式通常比多重继承更直观.

缺点

  • 虽然使用MyClass()创建的对象将是真正的单例对象,但MyClass本身是一个函数,而不是一个类,因此您无法从中调用类方法.也是为了m = MyClass(); n = MyClass(); o = type(n)();那时m == n && m != o && n != o

方法2:基类

class 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 singleton metaclass decorator base-class

829
推荐指数
14
解决办法
29万
查看次数

元类的一些(具体)用例是什么?

我有一个朋友喜欢使用元类,并定期提供它们作为解决方案.

我很想你几乎不需要使用元类.为什么?因为我认为如果你正在对一个类做类似的事情,你应该把它做成一个对象.并且需要一个小的重新设计/重构.

能够使用元类导致许多地方的很多人使用类作为某种二流对象,这对我来说似乎是灾难性的.编程是否被元编程取代?遗憾的是,类装饰器的添加使其更加可接受.

所以,我非常想知道Python中元类的有效(具体)用例.或者开悟为什么变异类有时比变异对象更好.

我将开始:

有时,在使用第三方库时,能够以某种方式改变类是有用的.

(这是我能想到的唯一一个案例,并不具体)

python metaclass

103
推荐指数
10
解决办法
2万
查看次数

什么时候(为什么)引入Python`__new __()`?

何时(为什么)__new__()引入了Python 函数?

创建类的实例需要三个步骤,例如MyClass()

  • MyClass.__call__()叫做。此方法必须在的元类中定义MyClass
  • MyClass.__new__()被调用__call__MyClass自行定义。这将创建实例。
  • MyClass.__init__()被(也称为__call__)。这将初始化实例。

实例的创建会受到重载__call__或的影响__new__。通常没有理由重载__call__而不是重载__new__(例如,使用元类的__call__方法而不是__new__?)。

我们有一些旧代码(仍然运行得很强大!),其中__call__的重载位置。给出的原因是__new__当时尚不可用。因此,我尝试了解有关Python和我们的代码的历史的更多信息,但是我不知道何时__new__引入。

__new__出现在用于Python 2.4文档,而不是在那些Python 2.3中,但它不会出现在whathsnew任何Python 2中的版本。我可以找到的第一个提交__new__(将descr-branch合并回主干。)是2001年开始的,但是“ back into trunk”消息表明以前有过。几个月前的PEP 252(使类型看起来更像类)PEP 253(对内置类型进行子类型化)似乎很重要。

学习更多有关引入的知识__new__将使我们更多地了解Python为何如此。


编辑以澄清:

似乎class.__new__重复了所提供的功能metaclass.__call__。添加仅以更好的方式复制现有功能的方法似乎不符合Pythonic。

__new__是您可以直接使用的少数几个类方法之一(cls例如,第一个参数),从而引入了以前没有的复杂性。如果类是函数的第一个参数,则可以认为该函数应该是元类的常规方法。但是该方法已经存在:__call__()。我觉得我想念什么。

应该有一种-最好只有一种-显而易见的方法。

python oop python-2.x

14
推荐指数
2
解决办法
803
查看次数

python3元类的调用顺序

当试图了解metaclass创建类实例的顺序时,我感到困惑。根据此),在此处输入图片说明

我输入以下代码进行验证。

class Meta(type):
    def __call__(self):
        print("Meta __call__")
        super(Meta, self).__call__()

    def __new__(mcs, name, bases, attrs, **kwargs):
        print("Meta __new__")
        return super().__new__(mcs, name, bases, kwargs)

    def __prepare__(msc, name, **kwargs):
        print("Meta __prepare__")
        return {}

class SubMeta(Meta):
    def __call__(self):
        print("SubMeta __call__!")
        super().__call__()

    def __new__(mcs, name, bases, attrs, **kwargs):
        print("SubMeta __new__")
        return super().__new__(mcs, name, bases, kwargs)

    def __prepare__(msc, name, **kwargs):
        print("SubMeta __prepare__")
        return Meta.__prepare__(name, kwargs)

class B(metaclass = SubMeta):
    pass

b = B()
Run Code Online (Sandbox Code Playgroud)

但是,结果似乎不像下面这样。

SubMeta __prepare__
Meta …
Run Code Online (Sandbox Code Playgroud)

python metaclass

5
推荐指数
2
解决办法
638
查看次数

标签 统计

python ×4

metaclass ×3

base-class ×1

decorator ×1

oop ×1

python-2.x ×1

singleton ×1