Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我应该在这里使用元类吗?_Python_Metaprogramming_Metaclass - Fatal编程技术网

Python 我应该在这里使用元类吗?

Python 我应该在这里使用元类吗?,python,metaprogramming,metaclass,Python,Metaprogramming,Metaclass,我正在读取一些数据,我想从中创建类——这是在加载时完成的。这些类被分组到一个特殊的类中,该类只能使用运行时信息进行实例化。这些类依赖于这个特殊的类,因此它们只有在创建之后才有用。下面是一些简化的代码,它显示了我希望它如何工作,使用random而不是实际的运行时信息: import random def make_foo(param1, param2): class Foo: def __init__(self, special): self.par

我正在读取一些数据,我想从中创建类——这是在加载时完成的。这些类被分组到一个
特殊的
类中,该类只能使用运行时信息进行实例化。这些类依赖于这个
特殊的
类,因此它们只有在创建之后才有用。下面是一些简化的代码,它显示了我希望它如何工作,使用
random
而不是实际的运行时信息:

import random
def make_foo(param1, param2):
    class Foo:
        def __init__(self, special):
            self.param1 = param1
            self.param2 = param2
            self.special = special
        def do(self):
            print "%s is doing" % self
        def __str__(self):
            return "Foo<%s,%s with %s>" % (self.param1, self.param2,
                                           self.special)

    return Foo
def make_bar(foo):
    class Bar:
        def __init__(self, special):
            self.foo = foo(special)
        def do(self):
            print "%s is doing" % (self,)
        def __str__(self):
            return "Bar<%s>" % self.foo
    return Bar

def make_grouper(foobars):
    class Grouper:
        def __init__(self, special):
            self.foobars = [foobar(special) for foobar in foobars]
    return Grouper

def make_special(howtomake, groups):
    class Special:
        def __init__(self):
            self.important = random.choice(howtomake)
            self.groups = [group(self) for group in groups]
        def __str__(self):
            return "Special<%s>" % self.important
    return Special

Foo10_20 = make_foo(10, 20)
Foo30_40 = make_foo(30, 40)
Bar = make_bar(Foo10_20)
Grouper1 = make_grouper([Foo10_20, Foo30_40])
Grouper2 = make_grouper([Bar, Bar])

Special = make_special("IMPORTANTINFO", [Grouper1, Grouper2])

s = Special()
s.groups[0].foobars[0].do()
s.groups[0].foobars[1].do()
s.groups[1].foobars[0].do()

s = Special()
s.groups[0].foobars[0].do()
s.groups[0].foobars[1].do()
s.groups[1].foobars[0].do()
随机导入
def make_foo(参数1,参数2):
Foo类:
定义初始(自我,特殊):
self.param1=param1
self.param2=param2
self.special=特殊
def do(自我):
打印“%s”正在进行“%self”
定义(自我):
返回“Foo”%(self.param1、self.param2、,
自我保护(特殊)
返回Foo
def make_bar(foo):
分类栏:
定义初始(自我,特殊):
self.foo=foo(特殊)
def do(自我):
打印“%s”正在执行“%(自身)
定义(自我):
返回“条”%self.foo
回程杆
def make_石斑鱼(食物棒):
石斑鱼:
定义初始(自我,特殊):
self.foobars=[foobars中foobar的foobar(专用)
返回石斑鱼
def使_特殊(如何制作,组):
特殊类别:
定义初始化(自):
self.important=随机选择(howtomake)
self.groups=[组(self)表示组中的组]
定义(自我):
返回“特殊”%self.important
退货特价
Foo10_20=make_foo(10,20)
Foo30_40=make_foo(30,40)
杆=制造杆(Foo10\u 20)
Grouper1=制作石斑鱼([Foo10\u20,Foo30\u40])
Grouper2=制作石斑鱼([Bar,Bar])
特殊=使_特殊(“重要信息”,[Grouper1,Grouper2])
s=特殊()
s、 组[0]。foobars[0]。do()
s、 组[0]。foobars[1]。do()
s、 组[1]。foobars[0]。do()
s=特殊()
s、 组[0]。foobars[0]。do()
s、 组[0]。foobars[1]。do()
s、 组[1]。foobars[0]。do()
样本输出:

Foo<10,20 with Special<O>> is doing
Foo<30,40 with Special<O>> is doing
Bar<Foo<10,20 with Special<O>>> is doing
Foo<10,20 with Special<I>> is doing
Foo<30,40 with Special<I>> is doing
Bar<Foo<10,20 with Special<I>>> is doing
Foo正在做什么
福在做什么
酒吧在做什么
福在做什么
福在做什么
酒吧在做什么

它可以概括为必须创建一组需要绑定到
特殊
参数的类(因此,所有构造函数在完成类之后,只需接受一个
特殊
参数)。使用元类可以更优雅地实现这一点吗?或者,这段代码是这样的吗?

因为我通常更喜欢Python中的闭包类,所以我在这里使用工厂类,避免同时使用动态创建的类。例如:

class Foo:
    def __init__(self, param1, param2, special):
        self.param1 = param1
        self.param2 = param2
        self.special = special
    def do(self):
        print "%s is doing" % self
    def __str__(self):
        return "Foo<%s,%s with %s>" % (self.param1, self.param2,
                                       self.special)

class FooFactory:
    def __init__(self, param1, param2):
        self.param1 = param1
        self.param2 = param2
    def __call__(self, special):
        return Foo(self.param1, self.param2, special)

foo_factory = FooFactory(1, 2)
foo = foo_factory(3)
并使用创建
Foo
的实例

FooSpecialised(special)

因为我通常更喜欢Python中的闭包类,所以我在这里使用工厂类,避免同时使用动态创建的类。例如:

class Foo:
    def __init__(self, param1, param2, special):
        self.param1 = param1
        self.param2 = param2
        self.special = special
    def do(self):
        print "%s is doing" % self
    def __str__(self):
        return "Foo<%s,%s with %s>" % (self.param1, self.param2,
                                       self.special)

class FooFactory:
    def __init__(self, param1, param2):
        self.param1 = param1
        self.param2 = param2
    def __call__(self, special):
        return Foo(self.param1, self.param2, special)

foo_factory = FooFactory(1, 2)
foo = foo_factory(3)
并使用创建
Foo
的实例

FooSpecialised(special)

这并不是严格意义上的答案(或者可能是),但我认为Tim Peters引用的这句话(MarkLutz,learning python 4 ed)可能很有趣:

引用 老兵的comp.lang.python新闻组 Python核心开发人员Tim Peters(谁 也是著名的 “导入此”Python格言:

[元类]比 99%的用户都应该担心。 如果你想知道你是否需要它们, 你不知道那些 需要他们确信地知道 他们需要它们,而不需要一个 解释原因)


这并不是严格意义上的答案(或者可能是),但我认为Tim Peters引用的这句话(MarkLutz,learning python 4 ed)可能很有趣:

引用 老兵的comp.lang.python新闻组 Python核心开发人员Tim Peters(谁 也是著名的 “导入此”Python格言:

[元类]比 99%的用户都应该担心。 如果你想知道你是否需要它们, 你不知道那些 需要他们确信地知道 他们需要它们,而不需要一个 解释原因)


我最终制作了一个基类:

class Base(object):
    @classmethod
    def bind_init(cls, *args, **kwargs):
        def init(special):
            return cls(special, *args, **kwargs)
        return init
Foo等人现在是一个外观正常的非动态类:

class Foo(Base):
    def __init__(self, special, param1, param2):
        self.param1 = param1
        self.param2 = param2
        self.special = special
    def do(self):
        print "%s is doing" % self
    def __str__(self):
        return "Foo<%s,%s with %s>" % (self.param1, self.param2,
                                       self.special)

这最大限度地减少了代码重复(不必生成大量的工厂类),而且我更喜欢行话而不是类工厂。

我最终生成了一个基类:

class Base(object):
    @classmethod
    def bind_init(cls, *args, **kwargs):
        def init(special):
            return cls(special, *args, **kwargs)
        return init
Foo等人现在是一个外观正常的非动态类:

class Foo(Base):
    def __init__(self, special, param1, param2):
        self.param1 = param1
        self.param2 = param2
        self.special = special
    def do(self):
        print "%s is doing" % self
    def __str__(self):
        return "Foo<%s,%s with %s>" % (self.param1, self.param2,
                                       self.special)

这最大限度地减少了代码重复(不必生成大量的工厂类),我也更喜欢行话而不是类工厂。

是的,我读过,但没有读过,但谢谢你提出。我觉得我需要一些东西。。如果有什么的话,我所做的事情的概念是错误的。但是工厂的想法很有效,我正在使用它。是的,我读过,但没有理会,但是谢谢你提出它。我觉得我需要一些东西。。如果有什么的话,我所做的事情的概念是错误的。但是工厂的想法很有效,我正在使用它