V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
saximi
V2EX  ›  Python

请问这段代码错在哪里呢?

  •  
  •   saximi · 2017-08-23 23:13:59 +08:00 · 2802 次点击
    这是一个创建于 2430 天前的主题,其中的信息可能已经有所发展或是发生改变。

    class F(type):

        def __init__(self): 
    
                print("F init") 
    
        def __call__(self): 
    
                print("F call") 
    

    class C1(F):

        def __init__(self): 
    
                print("C1 init") 
    
        def __call__(self): 
    
                print("C1 call") 
    

    class C2(object,metaclass=F):

        pass 
    

    print("--------")

    c1=C1()

    c1()

    print("c1 OVER")

    c2=C2()

    c2()

    print("c2 OVER")

    上面代码报错如下,请问这是怎么回事呢?

    class C2(object,metaclass=F): 
    

    TypeError: init() takes 1 positional argument but 4 were given

    6 条回复    2017-08-26 11:01:55 +08:00
    lrxiao
        1
    lrxiao  
       2017-08-23 23:41:24 +08:00
    class = metaclass.__init__(name, base, dict)
    saximi
        2
    saximi  
    OP
       2017-08-23 23:55:05 +08:00
    @lrxiao 不是很明白呢,是说作为 metaclass 的类 F,它的 init 方法要带专门的参数么?具体到我给的例子,应该怎么改呢?谢谢
    saximi
        3
    saximi  
    OP
       2017-08-24 01:25:44 +08:00
    @lrxiao 关于出错信息,是不是说__init__方法应该要传入 4 个参数,但是实际只传了一个位置参数?
    ivechan
        4
    ivechan  
       2017-08-24 11:12:31 +08:00
    @saximi 不是,反过来。
    错误的意思是,你定义的 __int__ 方法只定义了一个参数(self),但是你传入了 4 个参数。

    当然,其实不是你显式传入的, 是因为如果你指定了某个 metaclass,那么 Python 会自动调用
    metaclass(name, bases, namespace, **kwds)。
    具体建议你查看别人的 metaclass 是怎么写的。
    saximi
        5
    saximi  
    OP
       2017-08-25 00:35:48 +08:00
    @ivechan 谢谢,我搞清楚 metaclass 的参数了,是这几个(self, what, bases, dict),代码也改对了。
    但是我进一步把程序改成如下所示就出错了。
    ```
    class F(type):
    def __init__(self,what,bases=None,dict=None):
    print("F init")
    def __call__(self):
    print("F call")

    class C2(F):
    pass

    print("begin")
    c2=C2()
    print("end")

    ```
    报错如下:
    c2=C2()
    TypeError: type.__new__() takes exactly 3 arguments (0 given)

    这个问题在哪里呢?
    ivechan
        6
    ivechan  
       2017-08-26 11:01:55 +08:00
    @saximi 你的 F 类是 metaclass, 你为什么要继承它?
    metaclass 是控制类的生成的,而不是作为父类使用的。
    如果你不是为了用 metaclass, 你没有必要去搞懂他, 事实上很多人都搞不清楚,先把其他简单的东西理解到了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5048 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 09:35 · PVG 17:35 · LAX 02:35 · JFK 05:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.