3

I was reading this interesting post on metaclasses What is a metaclass in Python?. The accepted answer shows how to create a class using type with the following signature.

type(name of the class, tuple of the parent class (for inheritance, can be empty), dictionary containing attributes names and values)

I tried to create 'type' class using the above signature and I was surprised that I was allowed to create one in the first place! Your views are appreciated!

type = type('type',(),{});

Second, after I created a type class using the above syntax, I was not able to do

myclass = type('myclass',(),{}); 

and type = type('type',(),{});

I got an error saying

Traceback (most recent call last): File "", line 1, in TypeError: object.new() takes no parameters

But, when I tried to the following, I could succeed.

class myclass(object):
    pass

I am puzzled coz, according to my understanding the above snippet should invoke type in an attempt to create the class 'myclass'. So whats going on!? Am I missing some detail?

1
  • 1
    For the record, type classes used to refer to metaclasses here are a misnomer; type classes are a widely used concept in Functional Programming languages such as Haskell and Scala and have nothing to do with metaclasses. Commented Apr 13, 2014 at 17:07

2 Answers 2

6

You've shadowed type with type with type = type('type',(),{})

Note that semi-colons are redundant in Python.

So you're creating a type that can't do anything.

That's why the later type breaks.

Sign up to request clarification or add additional context in comments.

8 Comments

Yes.. I agree.. I understand thats what is happening. But my question is Why does python even allow that and type being shadowed, how is class myclass(object) successfull? shouldnt it try to use the type class that I have created and therefore fail?
@Karthick Because it has a philosophy of "consenting adults" - you're allowed to over-ride any builtins... I could write a module that says str = int, hex = lambda L: return 'FF' - etc... Python is a language that is flexible and allows control if you explicitly wish to do so - this is almost always not what is required though, but the black magic is there if you find a need to use it
I can agree with the philosophy, and then again, I still don understand how type('myclass', (), {}) fails but Class myclass(Object) : pass succeeds
Because it's the difference between a definition and a construction
Well if I am overshadowing it, I should be able to do it INSTEAD of the default type rite and isnt it the purpose of over shadowing? Like for example, when you overload operator '+' in C++, you see only overloaded '+' not the default one.. You could either invoke it explicitly with a function or just say + . both would invoke my function not the default.
|
0

Definition

>>> shadow = type("type",(),{})
>>> shadow
<class '__main__.type'>
>>> isinstance(shadow,type)
True
>>> issubclass(shadow,type)
False
>>> shadow(int)

Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    shadow(int)
TypeError: object.__new__() takes no parameters

Construction

>>> class shadow(type):
    pass

>>> shadow
<class '__main__.shadow'>
>>> isinstance(shadow,type)
True
>>> issubclass(shadow,type)
True
>>> shadow(int)
<type 'type'>
>>> shadow(type)
<type 'type'>
>>> shadow(1)
<type 'int'>

Python (and Python C API): __new__ versus __init__

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.