Тъй.
>>> class A:
... pass
...
>>> A.__class__
<class 'type'>
>>> A.__base__
<class 'object'>
>>> A.__class__ = object
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __class__ assignment: only for heap types
>>> A.__base__ = type
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: readonly attribute
Но пък:
>>> A = type("A", (type,), {})
>>> A.__class__
<class 'type'>
>>> A.__base__
<class 'type'>
Сега, това е малко безумно, нали. :) Защото:
class Meta(type):
def __new__(self, cls, bases, attrs):
return type.__new__(self, cls, bases, attrs)
def metaFoo(self, a):
print(a)
A = Meta("A", (Meta,), {})
print(A.__class__) # <class '__main__.Meta'>
print(A.__base__) # <class '__main__.Meta'>
A.metaFoo(1) # TypeError: metaFoo() takes exactly 2 positional arguments (1 given)
a = A() # __new__() takes exactly 4 positional arguments (1 given)
Пайтън тук се чупи, защото няма "клас-методи". Тъй като А е едновременно и инстанция, и наследник на Meta, той не знае какво да прави с това metaFoo. По-точно знае - счита го за наследен метод, а не за метод на базовия клас. Втората грешка дори нямам идея що става. :)
В Ruby е по-забавно:
class Class
class << self
alias oldSelfNew new
def new arg=Object
p "baaaaa"
oldSelfNew arg
end
end
end
Klass = Class.new Class # baaaaa
Klass.superclass # Class
Klass.class # Class
class Klass
def self.bar
42
end
def foo
"foo"
end
end
Klass.bar # 42
Klass.class_eval "bar" # 42
Klass.instance_eval "bar" # 42
B = Klass.new # "baaaaa", след което TypeError: wrong instance allocation
b = B.new
В смисъл, втф? :) Защо вика клас-методът new на Class, a не instance-методът? Някво супер странно е.
Едит: Това в Руби е "хакерия", щото принципно не се позволява наследяване от Class:
irb(main):001:0> class A < Class
irb(main):002:1> end
TypeError: can't make subclass of Class
from (irb):1