Shouldn't __metaclass__ force the use of a metaclass in Python?
I've been trying to learn about metaclasses in Python. I get the main idea, but I can't seem to activate the mechanism. As I understand it, you can specify M to be as the metaclass when constructing a class K by setting __metaclass__
to M at the global or class level. To test this out, I wrote the following program:
p = print
class M(type):
def __init__(*args):
type.__init__(*args)
print("The rain in Spain")
p(1)
class ClassMeta:
__metaclass__ = M
p(2)
__metaclass__ = M
class GlobalMeta: pass
p(3)
M('NotMeta2', (), {})
p(4)
However, when I run it, I get the following output:
C:\Documents and Settings\Daniel Wong\Desktop>python --version Python 3.0.1 C:\Documents and Settings\Daniel Wong\Desktop>python meta.py 1 2 3 The rain in Spain 4
Shouldn't I see "The rain in Spain" after 1 and 2? What's going on here?
Asked by: Kellan331 | Posted: 06-12-2021
Answer 1
In Python 3 (which you are using) metaclasses are specified by a keyword parameter in the class definition:
class ClassMeta(metaclass=M):
pass
Specifying a __metaclass__
class property or global variable is old syntax from Python 2.x and not longer supported. See also "What's new in Python 3" and PEP 2115.
Answer 2
This works as you expect in Python 2.6 (and earlier), but in 3.0 metaclasses are specified differently:
class ArgMeta(metaclass=M): ...
Answered by: Chelsea460 | Posted: 07-01-2022
Answer 3
The syntax of metaclasses has changed in Python 3.0. The __metaclass__
attribute is no longer special at either the class nor the module level. To do what you're trying to do, you need to specify metaclass
as a keyword argument to the class
statement:
p = print
class M(type):
def __init__(*args):
type.__init__(*args)
print("The rain in Spain")
p(1)
class ClassMeta(metaclass=M): pass
Yields:
1
The rain in Spain
As you'd expect.
Answered by: David737 | Posted: 07-01-2022Similar questions
metaclass - __metaclass__ in Python 3
In Python2.7 this code can work very well, __getattr__ in MetaTable
will run. But in Python 3 it doesn't work.
class MetaTable(type):
def __getattr__(cls, key):
temp = key.split("__")
name = temp[0]
alias = None
if len(temp) > 1:
alias = temp[1]
return cls(name, alias)
class Table(object):
__metaclass__ = MetaTable...
metaclass - __metaclass__ in Python 3
In Python2.7 this code can work very well, __getattr__ in MetaTable
will run. But in Python 3 it doesn't work.
class MetaTable(type):
def __getattr__(cls, key):
temp = key.split("__")
name = temp[0]
alias = None
if len(temp) > 1:
alias = temp[1]
return cls(name, alias)
class Table(object):
__metaclass__ = MetaTable...
metaclass - python __metaclass__ doesn’t work
class UpperAttrMetaClass(type):
def __new__(upperattr_metaclass, future_class_name, future_class_parents, future_class_attr):
attrs = ((name, value) for name, value in future_class_attr.items() if not name.startswith('__'))
uppercase_attr = dict((name.upper(), value) for name, value in attrs)
return type.__new__(upperattr_metaclass,future_class_name, future_class_parents, uppercase_at...
Python __metaclass__ inheritance issue
My issue is that I am using a metaclass to wrap certain class methods in a timer for logging purposes.
For example:
class MyMeta(type):
@staticmethod
def time_method(method):
def __wrapper(self, *args, **kwargs):
start = time.time()
result = method(self, *args, **kwargs)
finish = time.time()
sys.stdout.write('instancemethod %s took %0...
metaclass - Finding __metaclass__ used before redefinition in Python
I want to redefine a __metaclass__ but I want to fall back to the metaclass which would have been used if I hadn't redefined.
class ComponentMetaClass(type):
def __new__(cls, name, bases, dct):
return <insert_prev_here>.__new__(cls, name, bases, dct)
class Component(OtherObjects):
__metaclass__ = ComponentMetaClass
From what I understand, the __metaclass__ used b...
python - Why can't I change the __metaclass__ attribute of a class?
I have a weird and unusual use case for metaclasses where I'd like to change the __metaclass__ of a base class after it's been defined so that its subclasses will automatically use the new __metaclass__. But that oddly doesn't work:
class MetaBase(type):
def __new__(cls, name, bases, attrs):
attrs["y"] = attrs["x"] + 1
return type.__new__(cls, name, bases, attr...
python - Dynamic Class Variables - locals() vs __metaclass__
To create dynamic class variables you seem to have two options - using locals() or __metaclass__. I am not a fan of assigning to locals() but it seems to work in a class definition and is more succinct than it's __metaclass__ alternative.
Is it reliable to use locals() in this way? What are the advantages/drawbacks for either solution?
python - Why __metaclass__ doesn't work?
After reading parts of Django source code, I want to do some test and write codes below to watch how metaclass works:
class MyMeta(type):
def __new__(cls, name, bases, attrs):
print cls, name, bases, attrs
return super(MyMeta, cls).__new__(cls, name, bases, attrs)
class AttrFiled(object): pass
class Test(MyMeta):
name = AttrField()
It always compl...
class - How does this use of Python's __metaclass__ work?
Here in this IPython Notebook I found a presentation about generators and functional programming. I stumbled upon __metaclass__:
Why are Real and float arguments of Accounting? What usually is there now is in bases, but is it required to write Real and...
python - __metaclass__ adding invalid attribute to class created?
metaclass adding invalid attribute to class?
Here is my code:
def __metaclass__(clsname, bases, dct):
dct["key1"] = "value1"
dct["invalid identifier"] = "value2"
return type(clsname, bases, dct)
class Cls():
pass
for name in dir(Cls):
if not name.startswith("_"):
print name
when I run it, I got:
>>>
invali...
Python 2.7 - Is this a valid use of __metaclass__?
Closed. This question needs details or clarity. It ...
metaclass - __metaclass__ in Python 3
In Python2.7 this code can work very well, __getattr__ in MetaTable
will run. But in Python 3 it doesn't work.
class MetaTable(type):
def __getattr__(cls, key):
temp = key.split("__")
name = temp[0]
alias = None
if len(temp) > 1:
alias = temp[1]
return cls(name, alias)
class Table(object):
__metaclass__ = MetaTable...
linux - Why protobuf generates python class with __metaclass__ attribute?
protobuf generates C++/Java classes, and these are static typed class, enough for encoding/decoding. Why it generates python classes with metaclass attribute: I would suppose ordinary class will be enough to do rpc, like C++/Java generated classes.
Why python should use dynamic class?
Thanks.
Still can't find your answer? Check out these communities...
PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python