标签: metaclass

5409
推荐指数
22
解决办法
75万
查看次数

836
推荐指数
4
解决办法
14万
查看次数

在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万
查看次数

Django的Meta类如何工作?

我正在使用Django,它允许人们通过使用向类添加额外的参数class Meta.

class FooModel(models.Model):
    ...
    class Meta:
        ...
Run Code Online (Sandbox Code Playgroud)

我在Python的文档中找到的唯一一件事是:

class FooMetaClass(type):
    ...

class FooClass:
    __metaclass__ = FooMetaClass
Run Code Online (Sandbox Code Playgroud)

但是,我不认为这是一回事.

python django metaclass

165
推荐指数
5
解决办法
9万
查看次数

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

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

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

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

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

我将开始:

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

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

python metaclass

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

理解Python中的元类和继承

关于元类,我有些困惑.

继承

class AttributeInitType(object):

   def __init__(self,**kwargs):
       for name, value in kwargs.items():
          setattr(self, name, value)

class Car(AttributeInitType):

    def __init__(self,**kwargs):
        super(Car, self).__init__(**kwargs)
    @property
    def description(self):
       return "%s %s %s %s" % (self.color, self.year, self.make, self.model)

c = Car(make='Toyota', model='Prius', year=2005, color='green')
print c.description
Run Code Online (Sandbox Code Playgroud)

与元类

class AttributeInitType(type):
   def __call__(self, *args, **kwargs):
       obj = type.__call__(self, *args)
       for name, value in kwargs.items():
           setattr(obj, name, value)
       return obj

class Car(object):
   __metaclass__ = AttributeInitType

   @property
   def description(self):
       return "%s %s %s %s" % (self.color, self.year, self.make, self.model) …
Run Code Online (Sandbox Code Playgroud)

python inheritance metaclass

58
推荐指数
1
解决办法
2万
查看次数

元类多重继承不一致

为什么是这样:

class MyType(type):
    def __init__(cls, name, bases, attrs):
        print 'created', cls
class MyMixin:
    __metaclass__ = MyType
class MyList(list, MyMixin): pass
Run Code Online (Sandbox Code Playgroud)

好的,按预期工作:

created <class '__main__.MyMixin'>
created <class '__main__.MyList'>
Run Code Online (Sandbox Code Playgroud)

但是这个:

class MyType(type):
    def __init__(cls, name, bases, attrs):
        print 'created', cls
class MyMixin:
    __metaclass__ = MyType
class MyObject(object, MyMixin): pass
Run Code Online (Sandbox Code Playgroud)

不行,并且如此爆炸?:

created <class '__main__.MyMixin'>
Traceback (most recent call last):
  File "/tmp/junk.py", line 11, in <module>
    class MyObject(object, MyMixin): pass
TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution
order …
Run Code Online (Sandbox Code Playgroud)

python metaclass

57
推荐指数
1
解决办法
2万
查看次数

Python Metaclass:理解'with_metaclass()'

我想问一下这个with_metaclass()调用在一个类的定义中意味着什么.

例如:

class Foo(with_metaclass(Cls1, Cls2)):
Run Code Online (Sandbox Code Playgroud)
  • 是一个特殊的情况,一个类继承了元类?
  • 新类也是元类吗?

python metaclass six-python

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

以某种方式使用abc.ABCMeta,它与Python 2.7和Python 3.5兼容

我想创建一个具有abc.ABCMeta元类的类,并且与Python 2.7和Python 3.5兼容.到目前为止,我只能在2.7或3.5上成功实现这一点 - 但从不同时在两个版本上.有人可以帮我一把吗?

Python 2.7:

import abc
class SomeAbstractClass(object):
    __metaclass__ = abc.ABCMeta
    @abc.abstractmethod
    def do_something(self):
        pass
Run Code Online (Sandbox Code Playgroud)

Python 3.5:

import abc
class SomeAbstractClass(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def do_something(self):
        pass
Run Code Online (Sandbox Code Playgroud)

测试

如果我们使用合适版本的Python解释器(Python 2.7 - >示例1,Python 3.5 - >示例2)运行以下测试,则它在以下两种情况下都会成功:

import unittest
class SomeAbstractClassTestCase(unittest.TestCase):
    def test_do_something_raises_exception(self):
        with self.assertRaises(TypeError) as error:
            processor = SomeAbstractClass()
        msg = str(error.exception)
        expected_msg = "Can't instantiate abstract class SomeAbstractClass with abstract methods do_something"
        self.assertEqual(msg, expected_msg)
Run Code Online (Sandbox Code Playgroud)

问题

在使用Python 3.5运行测试时,预期的行为不会发生(TypeError在实例化时不会引发SomeAbstractClass):

======================================================================
FAIL: test_do_something_raises_exception (__main__.SomeAbstractClassTestCase)
----------------------------------------------------------------------
Traceback …
Run Code Online (Sandbox Code Playgroud)

python metaclass abc python-2.7 python-3.5

45
推荐指数
4
解决办法
2万
查看次数

调用元类库时出错:function()参数1必须是代码,而不是str

我今天早些时候试图将threading.Condition子类化,但它没有成功.当我尝试子类化threading.Condition类时,这是Python解释器的输出:

>>> import threading
>>> class ThisWontWork(threading.Condition):
...     pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
    function() argument 1 must be code, not str
Run Code Online (Sandbox Code Playgroud)

有人可以解释这个错误吗?谢谢!

python inheritance metaclass class

43
推荐指数
3
解决办法
5万
查看次数