内置的关键字类型是指python中的函数还是类?

时间:2023-01-15 18:51:14

In most posts, people often say type is a built-in function if it is provided with one argument, and it is a metaclass if provided with 3 arguments.

在大多数帖子中,人们常说如果提供了一个参数,则type是内置函数,如果提供3个参数,则它是元类。

But in python's doc, the signature of type is:

但是在python的doc中,类型的签名是:

class type(object)
class type(name, bases, dict)

So, does it means type is a built-in class and not a built-in function even if it is provided with one argument?

那么,它是否意味着类型是一个内置类而不是内置函数,即使它提供了一个参数?

3 个解决方案

#1


2  

type is called a "metaclass" because it's a class that produces other classes (AKA types). It behaves like a normal class. In particular, it has the equivalent of a __new__ method that would look something like this in Python:

type被称为“元类”,因为它是一个产生其他类(AKA类型)的类。它的行为就像一个普通的类。特别是,它具有相当于__new__的方法,在Python中看起来像这样:

class type(object):

    def __new__(cls, *args):
        num_args = len(args)

        if num_args not in (1, 3):
            raise TypeError('type() takes 1 or 3 arguments')

        # type(x)
        if num_args == 1:
            return args[0].__class__

        # type(name, bases, dict)
        name, bases, attributes = args
        bases = bases or (object,)

        class Type(*bases):
            pass

        Type.__name__ = name

        qualpath = Type.__qualname__.rsplit('.', 1)[0]
        Type.__qualname__ = '.'.join((qualpath, name))

        for name, value in attributes.items():
            setattr(Type, name, value)

        return Type

Class = type('Class', (), {'i': 1})
instance = Class()

print(type(instance))  # -> Class
print(instance.__class__)  # -> Class
print(type(type(instance)))  # -> type
print(Class.i)  # -> 1
print(instance.i)  # -> 1

Note that when instantiating a class, the value of the new instance is whatever is returned from __new__. In the case of type, __new__ always returns a type object (AKA class). Here's an example of a class that extends int to use -1 as the default value instead of 0:

请注意,在实例化类时,新实例的值是从__new__返回的值。在类型的情况下,__ new__总是返回一个类型对象(AKA类)。这是一个扩展int的类的示例,使用-1作为默认值而不是0:

def Int__new__(cls, *args):
    if not args:
        return cls(-1)
    return super(cls, cls).__new__(cls, *args)

Int = type('Int', (int,), {'__new__': Int__new__})

i = Int()
print(type(i))  # -> Int
print(i.__class__)  # -> Int
print(type(type(i)))  # -> type
print(i)  # -> -1

j = Int(1)
print(j)  # -> 1

To really dig into how type works, take a look at the C code in type_new. You can see there (scroll down a few lines) that type(x) is a special case that immediately returns the type (AKA class) of x. When you do type(name, bases, dict), the type creation machinery is invoked.

要真正深入了解类型的工作方式,请查看type_new中的C代码。您可以看到(向下滚动几行)类型(x)是一种特殊情况,它会立即返回x的类型(AKA类)。键入(name,bases,dict)时,将调用类型创建机制。

For more fun, try the following:

要获得更多乐趣,请尝试以下方法:

type(object)
type(type)
isinstance(object, object)
isinstance(type, object)
type(1)
type(type(1))

#2


1  

The built-in type always returns a type object, which is basically a class. That's true whether it's the one-argument form or the three-argument form. In the one-argument case, the returned object is the type (class) of the argument. In the three argument case, the returned object is a new type object (class). In both cases the returned object can be used to instantiate new objects (instances of the class).

内置类型总是返回一个类型对象,它基本上是一个类。无论是单参数形式还是三参数形式,都是如此。在单参数的情况下,返回的对象是参数的类型(类)。在三参数的情况下,返回的对象是一个新的类型对象(类)。在这两种情况下,返回的对象都可用于实例化新对象(类的实例)。

Some classes can be used as metaclasses. That's a common use case for the three-argument form of type. But there are other ways to make a class that can be used as a metaclass, and other uses for the three-argument form of type.

某些类可以用作元类。这是三参数形式的常见用例。但是还有其他方法可以创建一个可以用作元类的类,以及三参数形式的其他用法。

It's not that much different from int, which is a built-in function that returns an object of type int. int is also the name of a class, and can be used to create new objects:

它与int没有太大的不同,int是一个返回int类型对象的内置函数。 int也是类的名称,可用于创建新对象:

>>> x = int()
>>> x
0
>>> type(x)
<class 'int'>

And also like type, it has more than one form:

而且就像类型一样,它有多种形式:

>>> y = int("A", 16)
>>> y
10

#3


0  

The distinction between classes and functions in Python is not as stark as in other languages.

Python中类和函数之间的区别并不像其他语言那样明显。

You can use function call syntax to invoke an actual function, but also an instance of a class with the __call__ method, and even a class that overrides __new__ can behave like a function.

您可以使用函数调用语法来调用实际函数,也可以使用__call__方法调用类的实例,甚至覆盖__new__的类也可以像函数一样运行。

The word Python uses for all these is callable: an object you can invoke using the call syntax (foo()), which evaluates to a result.

Python用于所有这些的词是可调用的:你可以使用调用语法(foo())调用的对象,它会计算结果。

The type built-in is a callable. It can be called.

内置类型是可调用的。它可以被称为。

Sometimes you treat type like a function, and it works, so you can say it's a function. Other times you treat it like a class, so you can say it's a class. The actual implementation should not matter.

有时候你会把类型视为一个函数,它可以工作,所以你可以说它是一个函数。其他时候你把它当成一个类,所以你可以说它是一个类。实际执行无关紧要。

This is duck typing in action: if it walks like a duck, and it quacks like a duck, then it must be a duck.

这是鸭子打字行动:如果它像鸭子一样走路,它像鸭子一样嘎嘎叫,那它一定是鸭子。

#1


2  

type is called a "metaclass" because it's a class that produces other classes (AKA types). It behaves like a normal class. In particular, it has the equivalent of a __new__ method that would look something like this in Python:

type被称为“元类”,因为它是一个产生其他类(AKA类型)的类。它的行为就像一个普通的类。特别是,它具有相当于__new__的方法,在Python中看起来像这样:

class type(object):

    def __new__(cls, *args):
        num_args = len(args)

        if num_args not in (1, 3):
            raise TypeError('type() takes 1 or 3 arguments')

        # type(x)
        if num_args == 1:
            return args[0].__class__

        # type(name, bases, dict)
        name, bases, attributes = args
        bases = bases or (object,)

        class Type(*bases):
            pass

        Type.__name__ = name

        qualpath = Type.__qualname__.rsplit('.', 1)[0]
        Type.__qualname__ = '.'.join((qualpath, name))

        for name, value in attributes.items():
            setattr(Type, name, value)

        return Type

Class = type('Class', (), {'i': 1})
instance = Class()

print(type(instance))  # -> Class
print(instance.__class__)  # -> Class
print(type(type(instance)))  # -> type
print(Class.i)  # -> 1
print(instance.i)  # -> 1

Note that when instantiating a class, the value of the new instance is whatever is returned from __new__. In the case of type, __new__ always returns a type object (AKA class). Here's an example of a class that extends int to use -1 as the default value instead of 0:

请注意,在实例化类时,新实例的值是从__new__返回的值。在类型的情况下,__ new__总是返回一个类型对象(AKA类)。这是一个扩展int的类的示例,使用-1作为默认值而不是0:

def Int__new__(cls, *args):
    if not args:
        return cls(-1)
    return super(cls, cls).__new__(cls, *args)

Int = type('Int', (int,), {'__new__': Int__new__})

i = Int()
print(type(i))  # -> Int
print(i.__class__)  # -> Int
print(type(type(i)))  # -> type
print(i)  # -> -1

j = Int(1)
print(j)  # -> 1

To really dig into how type works, take a look at the C code in type_new. You can see there (scroll down a few lines) that type(x) is a special case that immediately returns the type (AKA class) of x. When you do type(name, bases, dict), the type creation machinery is invoked.

要真正深入了解类型的工作方式,请查看type_new中的C代码。您可以看到(向下滚动几行)类型(x)是一种特殊情况,它会立即返回x的类型(AKA类)。键入(name,bases,dict)时,将调用类型创建机制。

For more fun, try the following:

要获得更多乐趣,请尝试以下方法:

type(object)
type(type)
isinstance(object, object)
isinstance(type, object)
type(1)
type(type(1))

#2


1  

The built-in type always returns a type object, which is basically a class. That's true whether it's the one-argument form or the three-argument form. In the one-argument case, the returned object is the type (class) of the argument. In the three argument case, the returned object is a new type object (class). In both cases the returned object can be used to instantiate new objects (instances of the class).

内置类型总是返回一个类型对象,它基本上是一个类。无论是单参数形式还是三参数形式,都是如此。在单参数的情况下,返回的对象是参数的类型(类)。在三参数的情况下,返回的对象是一个新的类型对象(类)。在这两种情况下,返回的对象都可用于实例化新对象(类的实例)。

Some classes can be used as metaclasses. That's a common use case for the three-argument form of type. But there are other ways to make a class that can be used as a metaclass, and other uses for the three-argument form of type.

某些类可以用作元类。这是三参数形式的常见用例。但是还有其他方法可以创建一个可以用作元类的类,以及三参数形式的其他用法。

It's not that much different from int, which is a built-in function that returns an object of type int. int is also the name of a class, and can be used to create new objects:

它与int没有太大的不同,int是一个返回int类型对象的内置函数。 int也是类的名称,可用于创建新对象:

>>> x = int()
>>> x
0
>>> type(x)
<class 'int'>

And also like type, it has more than one form:

而且就像类型一样,它有多种形式:

>>> y = int("A", 16)
>>> y
10

#3


0  

The distinction between classes and functions in Python is not as stark as in other languages.

Python中类和函数之间的区别并不像其他语言那样明显。

You can use function call syntax to invoke an actual function, but also an instance of a class with the __call__ method, and even a class that overrides __new__ can behave like a function.

您可以使用函数调用语法来调用实际函数,也可以使用__call__方法调用类的实例,甚至覆盖__new__的类也可以像函数一样运行。

The word Python uses for all these is callable: an object you can invoke using the call syntax (foo()), which evaluates to a result.

Python用于所有这些的词是可调用的:你可以使用调用语法(foo())调用的对象,它会计算结果。

The type built-in is a callable. It can be called.

内置类型是可调用的。它可以被称为。

Sometimes you treat type like a function, and it works, so you can say it's a function. Other times you treat it like a class, so you can say it's a class. The actual implementation should not matter.

有时候你会把类型视为一个函数,它可以工作,所以你可以说它是一个函数。其他时候你把它当成一个类,所以你可以说它是一个类。实际执行无关紧要。

This is duck typing in action: if it walks like a duck, and it quacks like a duck, then it must be a duck.

这是鸭子打字行动:如果它像鸭子一样走路,它像鸭子一样嘎嘎叫,那它一定是鸭子。