Python不像C++和JAVA等语言,各种class不需要在类体明确声明变量(属性)及函数(方法),因此在使用第三方库的时候,如果帮助文档不完整,就很难通过源代码去查看某个类有哪些属性和方法。在网上查了些资料,并动手实践了下,大致可以通过四种办法来获取某个类/对象的属性及方法。
方法名 | 说明 |
---|---|
dir | 类及实例均会显示所有属性和方法,包括继承来的及动态添加的,但无法区分方法和属性 |
vars | 不会显示父类的内容。object的vars只会显示实例属性,class的vars会显示所有方法和类属性,属性和方法会区分显示 |
type | class的type就是type,object的type是相应的class,子类的type不会显示继承于哪个父类 |
help | 显示所有方法和类属性(不含实例属性),并对父类和子类的属性和方法进行区分 |
定义类如下
class Base:
Base_Class_Variable = 1 # 类属性
def __init__(self):
self.name = "Base" # 实例属性
def base_object_fun(self): #实例方法(普通方法)
print("This is a Base object function.")
@classmethod
def base_class_fun(cls): # 类方法
print("This is a Base class function.")
@staticmethod
def base_static_fun(): # 静态方法
print("This is a Base static function.")
@property
def base_property_fun(self): #property方法
print("This is a Base property function.")
class Child(Base):
Child_Class_Variable = 2
def __init__(self):
self.name = "Child"
def child_object_fun(self):
print("This is a Child object function.")
@classmethod
def child_class_fun(cls):
print("This is a Child class function.")
@staticmethod
def child_static_fun():
print("This is a Child static function.")
@property
def child_property_fun(self):
print("This is a Child property function.")
if __name__ == '__main__':
base = Base()
child = Child()
dir
dir返回该类的所有属性及方法,包括从父类继承来的属性。可以发现dir不会对变量和方法进行区分:
print(dir(Base))
"""Base的dir中有类属性和方法
['Base_Class_Variable',
'__class__',
'__delattr__',
'__dict__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__le__',
'__lt__',
'__module__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__weakref__',
'base_class_fun',
'base_object_fun',
'base_property_fun',
'base_static_fun']
"""
实例包含类的所有属性和方法,同时也会增加新的属性。比如在__init__中增加的name属性
print(dir(base))
"""
[……前面一部分同dir(Base),下同
'name'] # base实例增加的实例属性
"""
子类的dir会继承父类的所有方法和属性
print(dir(Child))
"""Base类有的Child也有,Child还有自己的属性和方法
[……同dir(Base)
'Child_Class_Variable', #Child类增加的属性
'child_class_fun', #Child类增加的方法
'child_object_fun', #Child类增加的方法
'child_property_fun', #Child类增加的方法
'child_static_fun'] #Child类增加的方法
"""
print(dir(child))
"""
[……同dir(Child)
'name'] #child实例增加的属性(覆盖了Base的同名属性)
"""
vars
vars 返回对象的__dict__属性,与直接调用.__dict__
效果一样。dict存储的是类/实例的属性和方法,不含父类继承来的。
当dict作用于类的时候,会显示该类方法、类属性,不显示实例属性。作用于实例的时候,会显示实例属性,不显示类属性及方法。
Base的dict有类属性和所有方法,且很容易区分
print(vars(Base))
"""
{'__module__': '__main__',
'Base_Class_Variable': 1,
'__init__': <function Base.__init__ at 0x0000024F1D4296A8>,
'base_object_fun': <function Base.base_object_fun at 0x0000024F1D429950>,
'base_class_fun': <classmethod object at 0x0000024F1D43C828>,
'base_static_fun': <staticmethod object at 0x0000024F1D43C860>,
'base_property_fun': <property object at 0x0000024F1D432868>,
'__dict__': <attribute '__dict__' of 'Base' objects>,
'__weakref__': <attribute '__weakref__' of 'Base' objects>,
'__doc__': None}
"""
base只会显示实例的属性
print(vars(base))
"""
{'name': 'Base'}
"""
做一个有趣的实验,给Base和base增加动态增加一个属性后再看下二者的dict:
Base.new_class_variable = "Base.new_class_variable"
base.new_object_variable = "base.new_object_variable"
print(vars(Base))
"""
{……与Base类的dict相同
'new_class_variable': 'Base.new_class_variable'} #增加了一行类变量,但未增加实例变量
"""
print(vars(base))
"""
{……与base实例的dict相同
'new_object_variable': 'base.new_object_variable'} #增加了一行实例变量,但未增加类变量
"""
Child子类不会显示Base的任何内容,无论是初始化内容还是动态添加的
print(vars(Child))
"""Child类的dict不包含Base的dict
{'__module__': '__main__',
'Child_Class_Variable': 2,
'__init__': <function Child.__init__ at 0x0000020C39BB9D08>,
'child_object_fun': <function Child.child_object_fun at 0x0000020C39BB9D90>,
'child_class_fun': <classmethod object at 0x0000020C39BCC908>,
'child_static_fun': <staticmethod object at 0x0000020C39BCC940>,
'child_property_fun': <property object at 0x0000020C39BD9548>,
'__doc__': None}
"""
print(vars(child))
"""child实例的dict不包含Child及Base类的方法和属性
{'name': 'Child'}
"""
type
type(class)返回的是type,type(object)返回的是类
print(type(Base))
"""类的type就是type
<class 'type'>
"""
print(type(base))
"""实例的type是类
<class '__main__.Base'>
"""
子类的类Type仍然是type,子类的实例type是子类,且不会显示继承的哪个父类,因此要知道该子类继承了哪些父类仍然要查看源代码
print(type(Child))
"""
<class 'type'>
"""
print(type(child))
"""
<class '__main__.Child'>
"""
help
help会显示类继承自哪个哪个父类,所有的属性和方法也都会显示是来自子类的定义还是父类的定义,会提示方法的优先级。
Base类的help与base实例的help,除了第一句话的解释有一点不同外,其它基本一样。注意到base的help并不显示实例属性。
print(help(Base))
"""
Help on class Base in module __main__:
class Base(builtins.object)
| Methods defined here:
|
| __init__(self)
| Initialize self. See help(type(self)) for accurate signature.
|
| base_object_fun(self)
|
| ----------------------------------------------------------------------
| Class methods defined here:
|
| base_class_fun() from builtins.type
|
| ----------------------------------------------------------------------
| Static methods defined here:
|
| base_static_fun()
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
|
| base_property_fun
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| Base_Class_Variable = 1
None
"""
print(help(base))
"""
Help on Base in module __main__ object: #只有这句话有一点不同,剩下的完全一致
class Base(builtins.object)
| Methods defined here:
|
| __init__(self)
| Initialize self. See help(type(self)) for accurate signature.
|
| base_object_fun(self)
|
| ----------------------------------------------------------------------
| Class methods defined here:
|
| base_class_fun() from builtins.type
|
| ----------------------------------------------------------------------
| Static methods defined here:
|
| base_static_fun()
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
|
| base_property_fun
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| Base_Class_Variable = 1
None
"""
子类的help会包含父类的方法和属性,包括动态增加的属性,子类实例的help与子类也只有第一句不一样,但也可以发现子类实例的help中并不包含实例属性。
print(help(Child))
"""Child类的help会包含Base类的所有方法和属性,包括动态增加的属性
Help on class Child in module __main__:
class Child(Base)
| Method resolution order:
| Child
| Base
| builtins.object
|
| Methods defined here:
|
| __init__(self)
| Initialize self. See help(type(self)) for accurate signature.
|
| child_object_fun(self)
|
| ----------------------------------------------------------------------
| Class methods defined here:
|
| child_class_fun() from builtins.type
|
| ----------------------------------------------------------------------
| Static methods defined here:
|
| child_static_fun()
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| child_property_fun
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| Child_Class_Variable = 2
|
| ----------------------------------------------------------------------
| Methods inherited from Base:
|
| base_object_fun(self)
|
| ----------------------------------------------------------------------
| Class methods inherited from Base:
|
| base_class_fun() from builtins.type
|
| ----------------------------------------------------------------------
| Static methods inherited from Base:
|
| base_static_fun()
|
| ----------------------------------------------------------------------
| Data descriptors inherited from Base:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
|
| base_property_fun
|
| ----------------------------------------------------------------------
| Data and other attributes inherited from Base:
|
| Base_Class_Variable = 1
|
| new_class_variable = 'Base.new_class_variable'
None
"""
print(help(child))
"""
Help on Child in module __main__ object: #只有这一句不同
class Child(Base)
| Method resolution order:
| Child
| Base
| builtins.object
|
| Methods defined here:
|
| __init__(self)
| Initialize self. See help(type(self)) for accurate signature.
|
| child_object_fun(self)
|
| ----------------------------------------------------------------------
| Class methods defined here:
|
| child_class_fun() from builtins.type
|
| ----------------------------------------------------------------------
| Static methods defined here:
|
| child_static_fun()
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| child_property_fun
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| Child_Class_Variable = 2
|
| ----------------------------------------------------------------------
| Methods inherited from Base:
|
| base_object_fun(self)
|
| ----------------------------------------------------------------------
| Class methods inherited from Base:
|
| base_class_fun() from builtins.type
|
| ----------------------------------------------------------------------
| Static methods inherited from Base:
|
| base_static_fun()
|
| ----------------------------------------------------------------------
| Data descriptors inherited from Base:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
|
| base_property_fun
|
| ----------------------------------------------------------------------
| Data and other attributes inherited from Base:
|
| Base_Class_Variable = 1
|
| new_class_variable = 'Base.new_class_variable'
None
"""