Obtain object information (Liao Xuefeng)

When we get a reference to an object, how do we know what type this object is and what methods are there?

Use type ()

First, let's determine the object type and use the type()function:

Basic types can be type()judged:

>>> type(123)
<class 'int'>
>>> type('str')
<class 'str'>
>>> type(None)
<type(None) 'NoneType'>

If a variable points to a function or class, you can also use type()judgment:

>>> type(abs)
<class 'builtin_function_or_method'>
>>> type(a)
<class '__main__.Animal'>

But type()what type does the function return? It returns the corresponding Class type. If we want ifto judge in the statement, we need to compare whether the type types of the two variables are the same:

>>> type(123)==type(456)
True
>>> type(123)==int
True
>>> type('abc')==type('123')
True
>>> type('abc')==str
True
>>> type('abc')==type(123)
False

You can directly write the basic data type int, stretc., but what if you want to determine whether an object is a function? You can use typesthe constants defined in the module:

>>> import types
>>> def fn():
...     pass
...
>>> type(fn)==types.FunctionType
True
>>> type(abs)==types.BuiltinFunctionType
True
>>> type(lambda x: x)==types.LambdaType
True
>>> type((x for x in range(10)))==types.GeneratorType
True

Use isinstance ()

For the inheritance relationship of class, type()it is very inconvenient to use . We have to judge the type of class, we can use isinstance()functions.

We recall the previous example, if the inheritance relationship is:

object -> Animal -> Dog -> Husky

Then, isinstance()we can tell whether an object is of a certain type. First create three types of objects:

>>> a = Animal()
>>> d = Dog()
>>> h = Husky()

Then, judge:

>>> isinstance(h, Husky)
True

No problem, because the hvariable points to the Husky object.

Then judge:

>>> isinstance(h, Dog)
True

hAlthough it is a Husky type, Husky is hstill a Dog type because it inherited from Dog . In other words, isinstance()it is judged whether an object is the type itself, or is located on the type's parent inheritance chain.

Therefore, we can be sure that it his the Animal type:

>>> isinstance(h, Animal)
True

Similarly, the actual type is Dog dand Animal type:

>>> isinstance(d, Dog) and isinstance(d, Animal)
True

However, dnot the Husky type:

>>> isinstance(d, Husky)
False

Available type()basic types of determination may be used isinstance()to determine:

>>> isinstance('a', str)
True
>>> isinstance(123, int)
True
>>> isinstance(b'a', bytes)
True

And can also determine whether a variable is one of certain types, such as the following code can determine whether it is a list or tuple:

>>> isinstance([1, 2, 3], (list, tuple))
True
>>> isinstance((1, 2, 3), (list, tuple))
True
Always use isinstance () to determine the type, and you can "specify all types" of the specified type and its subclasses.

Use dir ()

If you want to get all the properties and methods of an object, you can use a dir()function, which returns a list containing strings, for example, to get all the properties and methods of a str object:

>>> dir('ABC')
['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']

Similar __xxx__properties and methods have special uses in Python, such as the __len__method return length. In Python, if you call a len()function to try to obtain the length of an object, in fact, inside the len()function, it automatically calls the __len__()method of the object , so the following code is equivalent:

>>> len('ABC')
3
>>> 'ABC'.__len__()
3

If we want to use the class we wrote len(myObj)ourselves, write a __len__()method by ourselves :

>>> class MyDog(object):
...     def __len__(self):
...         return 100
...
>>> dog = MyDog()
>>> len(dog)
100

The rest are ordinary attributes or methods, such as lower()returning a lowercase string:

>>> 'ABC'.lower()
'abc'

Only the properties and methods listed is not enough to meet getattr(), setattr()and hasattr()we can directly manipulate an object's status:

>>> class MyObject(object):
...     def __init__(self):
...         self.x = 9
...     def power(self):
...         return self.x * self.x
...
>>> obj = MyObject()

Next, you can test the properties of the object:

>>> hasattr(obj, 'x') # 有属性'x'吗?
True
>>> obj.x
9
>>> hasattr(obj, 'y') # 有属性'y'吗?
False
>>> setattr(obj, 'y', 19) # 设置一个属性'y'
>>> hasattr(obj, 'y') # 有属性'y'吗?
True
>>> getattr(obj, 'y') # 获取属性'y'
19
>>> obj.y # 获取属性'y'
19

If you try to get a non-existent attribute, an AttributeError will be thrown:

>>> getattr(obj, 'z') # 获取属性'z'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'MyObject' object has no attribute 'z'

You can pass in a default parameter, if the attribute does not exist, it returns the default value:

>>> getattr(obj, 'z', 404) # 获取属性'z',如果不存在,返回默认值404
404

You can also get the object method:

>>> hasattr(obj, 'power') # 有属性'power'吗?
True
>>> getattr(obj, 'power') # 获取属性'power'
<bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>>
>>> fn = getattr(obj, 'power') # 获取属性'power'并赋值到变量fn
>>> fn # fn指向obj.power
<bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>>
>>> fn() # 调用fn()与调用obj.power()是一样的
81

summary

Through a series of built-in functions, we can analyze any Python object and get its internal data. It should be noted that only when the object information is not known, we will get the object information. If you can write directly:

sum = obj.x + obj.y

Just do n’t write:

sum = getattr(obj, 'x') + getattr(obj, 'y')

An example of correct usage is as follows:

def readImage(fp):
    if hasattr(fp, 'read'):
        return readData(fp)
    return None

Suppose we want to read the image from the file stream fp, we first need to determine whether the fp object has a read method, if it exists, the object is a stream, if it does not exist, it cannot be read. hasattr()It came in handy.

Please note that in dynamic languages ​​such as Python, there are read()methods according to the duck type, which does not mean that the fp object is a file stream, it may also be a network stream, or it may be a byte stream in memory, but as long as the read()method returns What is valid image data, does not affect the function of reading the image.

Reference source code

get_type.py

attrs.py

Published 17 original articles · Like1 · Visits 819

Guess you like

Origin blog.csdn.net/weixin_45433031/article/details/105013320