26.Python编程:获取对象信息

作者: TensorFlow开发者 | 来源:发表于2018-06-04 20:47 被阅读9次
    # 创建一个猫类对象c
    c = Cat()
    c.eat()
    

    思考:当我们拿到一个对象的引用时,我们能通过该引用获取该对象的哪些信息呢?例如:创建了一个猫类对象c,我们能根据c,获取到哪些数据信息呢?

    再思考:一个对象哪些数据信息是我们开发时所关心的呢?正如你所想到的:对象所属的类型、对象的属性、方法等信息。

    本文就来通过对象的引用获取该对象类型、所有的属性和方法。

    接下来,我们用Python中自带的函数,来获取以上重要信息。现在我们设计object_info.py模块:包含了Animal类、Cat类、Dog类,代码如下。

    # 定义一个动物类Animal
    class Animal(object):
        legs = ''  # 腿的数量
        color = ''  # 毛色
    
        def eat(self):
            print("Animal吃东西")
    
        def sleep(self):
            print("Animal睡觉")
    
        def walk(self):
            print("Animal走路")
    
    
    # 定义一个猫类Cat,继承自动物类Animal
    class Cat(Animal):
    
        def eat(self):
            print("小猫吃鱼")
    
        def sleep(self):
            print("小猫呼呼睡觉")
    
        def walk(self):
            print("小猫走猫步")
    
    
    # 定义一个狗类Dog,继承自动物类Animal
    class Dog(Animal):
    
        def eat(self):
            print("小狗啃骨头")
    
        def sleep(self):
            print("小狗高度警惕的睡觉")
    
        def walk(self):
            print("小狗飞奔")
    
    

    获取类型type(obj)

    class type(obj)官方解释:

    With one argument, return the type of an object. The return value is a type object and generally the same object as returned by object.__class__.

    意思大概是说:type函数传入一个参数时,返回结果是该对象的类型。返回值是type对象,和调用该对象的__class__方法返回值一样。

    写出测试代码如下:

    # 创建猫类对象c1
    c1 = Cat()
    
    # type(obj)
    print("type(c1)", type(c1))
    print("c1.__class__", c1.__class__)
    

    运行结果:

    type(c1): <class '__main__.Cat'>
    c1.__class__: <class '__main__.Cat'>
    

    正如官方解释的一样:当type函数传入一个参数时,返回结果是该对象的类型,返回值和调用该对象的__class__方法返回值一样,是一type类型对象。

    看到打印结果,这里c1、c2的类型打印结果是:__main__.Cat,为什么多了一部分__main__?前面讲过__main__则是表示我直接运行的当前模块,也就是本例子中object_info.py模块,而不是该模块被其他模块唤起的。

    我们再设计另一个模块,my_test.py。文件结构如下:

    文件结构示意图
    from object_infos.object_info import Cat
    
    print("--object_info模块被唤起的---")
    
    

    这次我们运行my_test.py,因为该模块导入了object_info.py模块中的Cat类,所以object_info.py是被动唤起调用的。

    运行结果:

    type(c1): <class 'object_infos.object_info.Cat'>
    c1.__class__: <class 'object_infos.object_info.Cat'>
    --object_info模块被唤起的---
    

    看到打印结果,这里c1、c2的类型打印结果不再含有:__main__,而是打印的全类名:object_infos.object_info.Cat。即:object_infos包下的object_info模块中的Cat类。

    补充 isinstance(obj, type)

    isinstance(obj, type) 函数专门用于判断一个对象是否某个类型。官方解释:

    The isinstance() built-in function is recommended for testing the type of an object, because it takes subclasses into account.

    意思大概是:当试图判断一个对象是否某个类型时,推荐使用 Python内置的函数isinstance(obj, type),因为该函数会把具有继承关系的类考虑在内。

    这怎么理解呢?
    object_info.py模块中添加如下代码:

    # 创建狗类对象d
    d = Dog()
    print("isinstance(d, Dog):", isinstance(d, Dog))
    print("isinstance(d, Animal):", isinstance(d, Animal))
    

    运行结果:

    isinstance(d, Dog): True
    isinstance(d, Animal): True
    

    可以看到:狗对象d是狗类实例;狗对象d也是动物类实例,都是True。也就是我们通常所理解的:狗是狗(True),狗是动物(True)。因为Dog类继承自Aniaml类,所以Python内置的函数isinstance(obj, type),会把具有继承关系的类考虑在内。

    dir()函数:获取属性和方法

    如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法。dir()函数官方解释如下:

    Without arguments, return the list of names in the current local scope. With an argument, attempt to return a list of valid attributes for that object.

    意思大概是:dir()函数,如果调用时无参调用,则返回当前本地范围中的名称列表。如果调用时传入一个对象参数,则尝试返回该对象的所有的有效属性列表。

    也就是传一个对象参数则可返回该对象的所有属性和方法。由于dir()无参时涉及到上下文中,为了更好地看出无参和有餐的dir()函数调用区别,这里把整个模块objcet_info.py贴出来:

    # 定义一个动物类Animal
    class Animal(object):
        legs = ''  # 腿的数量
        color = ''  # 毛色
    
        def eat(self):
            print("Animal吃东西")
    
        def sleep(self):
            print("Animal睡觉")
    
        def walk(self):
            print("Animal走路")
    
    
    # 定义一个猫类Cat,继承自动物类Animal
    class Cat(Animal):
    
        def eat(self):
            print("小猫吃鱼")
    
        def sleep(self):
            print("小猫呼呼睡觉")
    
        def walk(self):
            print("小猫走猫步")
    
    
    # 定义一个狗类Dog,继承自动物类Animal
    class Dog(Animal):
    
        def eat(self):
            print("小狗啃骨头")
    
        def sleep(self):
            print("小狗高度警惕的睡觉")
    
        def walk(self):
            print("小狗飞奔")
    
    
    # 创建狗类对象d
    d = Dog()
    print("isinstance(d, Dog):", isinstance(d, Dog))
    print("isinstance(d, Animal):", isinstance(d, Animal))
    
    print("dir()无参调用:", dir())
    print("dir(d)传入参数时:", dir(d))
    

    运行结果:

    dir()无参调用: ['Animal', 'Cat', 'Dog', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'd']
    dir(d)传入参数时: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'color', 'eat', 'legs', 'sleep', 'walk']
    
    

    使用dir()函数,如果调用时无参调用,则返回当前本地范围中的名称列表,如:'Animal', 'Cat', 'Dog','d'等数据。
    如果调用时传入一个对象参数,则尝试返回该对象的所有的有效属性列表。如上运行结果所示。

    补充 class type(name, bases, dict)

    前面在将type()函数时,官方解释中强调了一个参数的,是因为还有一个同名函数,但需要传入三个参数的,可以动态创建新的class对象,也就是新类型,如:通过该函数动态创建Fox类。 class type(name, bases, dict)的官方解释如下:

    With three arguments, return a new type object. This is essentially a dynamic form of the class statement. The name string is the class name and becomes the name attribute; the bases tuple itemizes the base classes and becomes the bases attribute; and the dict dictionary is the namespace containing definitions for class body and is copied to a standard dictionary to become the dict attribute. For example, the following two statements create identical type objects。

    要创建一个class对象,type()函数依次传入3个参数:
    1.新class的名称;
    2.所要继承的父类的集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法;
    3.新class中的方法名称与函数可通过字典键值对一一绑定。例如:此参数传入:dict(my_eat=eat)这里我们把函数eat绑定到方法名my_eat上。

    通过type()函数创建的类和直接写class是完全一样的,因为Python解释器遇到class定义时,仅仅是扫描一下class定义的语法,然后调用type()函数创建出class。

    看到这里,你会发现这与Java中的反射机制类似的:运行时动态创建的对象、绑定属性、方法等。接下在学习元类时会专门学习这一块内容。

    小结

    本文通过对象的引用获取该对象类型、所有的属性和方法。

    type()函数传入一个参数时,返回结果是该对象的类型。返回值是type对象,和调用该对象的__class__方法返回值一样。

    isinstance(obj, type) 函数专门用于判断一个对象是否某个类型。

    dir()函数,如果调用时无参调用,则返回当前本地范围中的名称列表。如果调用时传入一个对象参数,则尝试返回该对象的所有的有效属性列表。

    class type(name, bases, dict)可以创建出新的类型。类似Java中的反射机制。

    相关文章

      网友评论

        本文标题:26.Python编程:获取对象信息

        本文链接:https://www.haomeiwen.com/subject/wfwysftx.html