杰瑞科技汇

Python中type和typeof有何区别?

Of course! This is a very common question for developers coming from languages like JavaScript, C, or Java.

Python中type和typeof有何区别?-图1
(图片来源网络,侵删)

In Python, the concept of "type" is more direct and powerful than a simple typeof operator. There are two main ways to get type information:

  1. type(obj): The most direct equivalent of typeof. It tells you the exact class an object was created from.
  2. isinstance(obj, class): The more "Pythonic" and flexible way. It checks if an object is an instance of a class or its subclasses. This is generally preferred.

Let's break them down.


The type() Function

The type() function returns the type of an object. This is the closest thing to a typeof operator.

How it Works:

You pass an object to type(), and it returns its class.

Python中type和typeof有何区别?-图2
(图片来源网络,侵删)
# Basic data types
my_int = 42
my_float = 3.14
my_str = "hello"
my_bool = True
my_list = [1, 2, 3]
my_dict = {"key": "value"}
print(f"42 is of type: {type(my_int)}")
print(f"3.14 is of type: {type(my_float)}")
print(f"'hello' is of type: {type(my_str)}")
print(f"True is of type: {type(my_bool)}")
print(f"[1, 2, 3] is of type: {type(my_list)}")
print(f"{{'key': 'value'}} is of type: {type(my_dict)}")

Output:

42 is of type: <class 'int'>
3.14 is of type: <class 'float'>
'hello' is of type: <class 'str'>
True is of type: <class 'bool'>
[1, 2, 3] is of type: <class 'list'>
{'key': 'value'} is of type: <class 'dict'>

Checking for Custom Classes:

It works perfectly with your own classes too.

class Dog:
    def __init__(self, name):
        self.name = name
my_dog = Dog("Rex")
print(f"my_dog is of type: {type(my_dog)}")

Output:

my_dog is of type: <class '__main__.Dog'>

The isinstance() Function

This is the more common and recommended way to check types in Python. It's more flexible because it understands inheritance.

Python中type和typeof有何区别?-图3
(图片来源网络,侵删)

How it Works:

You pass an object and a class (or a tuple of classes) to isinstance(). It returns True if the object is an instance of that class, or an instance of any of its subclasses.

class Animal:
    pass
class Dog(Animal): # Dog inherits from Animal
    pass
class Cat(Animal):
    pass
my_dog = Dog()
my_cat = Cat()
my_animal = Animal()
# Check if my_dog is a Dog
print(f"Is my_dog a Dog? {isinstance(my_dog, Dog)}") # True
# Check if my_dog is an Animal (because Dog inherits from Animal)
print(f"Is my_dog an Animal? {isinstance(my_dog, Animal)}") # True
# Check if my_cat is an Animal
print(f"Is my_cat an Animal? {isinstance(my_cat, Animal)}") # True
# Check if my_animal is a Dog
print(f"Is my_animal a Dog? {isinstance(my_animal, Dog)}") # False

Why isinstance() is often better:

  1. Handles Inheritance: As shown above, isinstance() correctly identifies an object as an instance of its parent class. type() does not.

    print(f"type(my_dog) == Animal -> {type(my_dog) == Animal}") # False
    print(f"isinstance(my_dog, Animal) -> {isinstance(my_dog, Animal)}") # True
  2. Can Check Against Multiple Types: You can pass a tuple of types to check against.

    def process_data(data):
        if isinstance(data, (int, float)):
            print(f"Processing a number: {data}")
        elif isinstance(data, str):
            print(f"Processing a string: {data}")
        else:
            print("Unknown data type")
    process_data(123)      # Processing a number: 123
    process_data("hello")   # Processing a string: hello
    process_data([1, 2])    # Unknown data type

The is Operator vs

It's important not to confuse isinstance() with using the is operator or .

  • obj is type: Checks for identity. It asks, "Is this object the exact same object in memory as this type object?" This is almost never what you want for type checking. type(42) is int is True, but it's not the right tool for the job.
  • type(obj) == type: Checks for equality. This works for simple types but fails with inheritance, just like isinstance succeeds. It's brittle.
class Animal: pass
class Dog(Animal): pass
my_dog = Dog()
# --- The WRONG way (fails with inheritance) ---
print(f"Wrong way: type(my_dog) == Animal -> {type(my_dog) == Animal}") # False
# --- The RIGHT way (handles inheritance) ---
print(f"Right way: isinstance(my_dog, Animal) -> {isinstance(my_dog, Animal)}") # True

Summary: When to Use Which?

Function What it Does When to Use It
type(obj) Returns the exact class of an object. When you need to know the precise class, not its parent. This is rare. It's the direct typeof equivalent.
isinstance(obj, class) Checks if an object is an instance of a class or its subclasses. This is the standard, preferred way. Use it for type checking, input validation, and conditional logic.
type(obj) is class Checks for object identity in memory. Almost never for type checking. Use for checking singletons like None (my_var is None).

Python 3.5+: Type Hinting (Type Hints)

For modern Python (3.5+), you'll also see "type hints" in your code. These are not for runtime type checking but for static analysis (by tools like MyPy) and to help developers understand the expected types.

from typing import List
def greet_all(names: List[str]) -> None:
    """Greets a list of people by name."""
    for name in names:
        print(f"Hello, {name}!")
# The type hint `List[str]` is a comment for the developer and linters.
# It does not stop you from passing a list of integers.
greet_all(["Alice", "Bob", "Charlie"]) # Works fine
greet_all([1, 2, 3]) # Static linters will flag this, but it will still run

To actually enforce these types at runtime, you need a library like Pydantic or typeguard.

Final Recommendation

For everyday Python programming, use isinstance(). It's more robust, flexible, and the idiomatic way to handle type checking. Use type() only when you have a specific need to know the exact class of an object, ignoring inheritance.

分享:
扫描分享到社交APP
上一篇
下一篇