Python如何查看对象的属性(函数、变量等)

Python
192
0
0
2024-03-21
标签   Python基础
背景故事

JIRA是一个缺陷跟踪管理系统,为针对缺陷管理、任务追踪和项目管理的商业性应用软件,开发者是澳大利亚的Atlassian。JIRA这个名字并不是一个缩写,而是截取自“Gojira”,日文的哥斯拉发音。在使用python调用testlink数据时,使用第三方模jira,获取jira数据。 在jira官网有一段描述如下:

A resource is connected to other resources, and the client preserves this connection. In the above example, the object inside the issue object at issue.fields.assignee is not just a dict – it is a full-fledged user Resource object. Whenever a resource contains other resources, the client will attempt to convert them to the proper subclass of Resource.

这意味着,作为一个issue资源,它自身包含的属性可能会链接到其它的资源,而issue对象只会保存其它资源的实例,而不是属性。

问题描述
# -*- coding: utf-8 -*-
# @Time    : 2020/6/8 11:00
# @Author  : lijiazhu@xunlei.com
# @FileName: jira_util.py
# @Software: PyCharm

import logging
from jira import JIRA
from libs.common.common_conf import _JIRA_SERVER_URL
from libs.common.common_conf import _JIRA_USER
from libs.common.common_conf import _JIRA_PASSWORD

jira_client = JIRA(server=_JIRA_SERVER_URL, basic_auth=(_JIRA_USER, _JIRA_PASSWORD))
_logger = logging.getLogger(__name__)


class JiraProxy(object):
    @classmethod
    def get_project_issues(cls, projectID, version):
        issues = []
        try:
            jira_issues_jql_str =  f"project = {projectID} AND issuetype = Bug  AND affectedVersion = {version}"
            jira_issues = jira_client.search_issues(jira_issues_jql_str, maxResults=5000)
            print(jira_issues)
        except Exception as e:
            _logger.error(f"get_project_issues exception: {e}")
        finally:
            _logger.info(f"get_project_issues, {projectID} {version}:  {issues}")
            return issues


if __name__ == "__main__":
    JiraProxy.get_project_issues("PTCP", "V6.17")

输出如下:

[<JIRA Issue: key='PTCP-15503', id='158323'>, <JIRA Issue: key='PTCP-15299', id='156704'>]

这意味着issue对象中有哪些属性、方法,都是未知的。

问题分析

那么如何知道一个未知的动态对象包含哪些属性呢?如Issue。 答案是可以使用python内置函数dir() https://docs.python.org/3/library/functions.html#dir

在这里插入图片描述

使用print(dir(issue))输出如下:

['JIRA_BASE_URL', '_IssueFields', '_READABLE_IDS', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattr__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_base_url', '_default_headers', '_get_url', '_load', '_options', '_parse_raw', '_resource', '_session', 'add_field_value', 'delete', 'expand', 'fields', 'find', 'id', 'key', 'permalink', 'raw', 'self', 'update']

那我们就知道Issue中有fields字段,这可能是有用的信息,继续使用print(dir(issue.fields)),输出如下:

['__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__', 'aggregateprogress', 'aggregatetimeestimate', 'aggregatetimeoriginalestimate', 'aggregatetimespent', 'assignee', 'components', 'created', 'creator', 'customfield_10101', 'customfield_10102', 'customfield_10104', 'customfield_10105', 'customfield_10106', 'customfield_10107', 'customfield_10109', 'customfield_10114', 'customfield_10118', 'customfield_10119', 'customfield_10121', 'customfield_10122', 'customfield_10123', 'customfield_10124', 'customfield_10304', 'customfield_10308', 'customfield_10400', 'customfield_10404', 'customfield_10405', 'customfield_10502', 'customfield_10506', 'customfield_10509', 'customfield_10604', 'customfield_10606', 'customfield_10609', 'customfield_10610', 'customfield_10611', 'customfield_10905', 'customfield_11201', 'customfield_11202', 'customfield_11203', 'customfield_11301', 'customfield_11303', 'customfield_11304', 'customfield_11305', 'customfield_11400', 'customfield_11401', 'customfield_11402', 'customfield_11403', 'customfield_11404', 'customfield_11408', 'customfield_11410', 'customfield_11411', 'customfield_11412', 'customfield_11413', 'customfield_11414', 'customfield_11415', 'customfield_11416', 'customfield_11417', 'customfield_11418', 'customfield_11419', 'customfield_11420', 'customfield_11421', 'customfield_11423', 'customfield_11427', 'customfield_11428', 'customfield_11600', 'customfield_11601', 'customfield_11602', 'customfield_11603', 'customfield_11604', 'customfield_11606', 'customfield_11607', 'customfield_11613', 'customfield_11616', 'customfield_11802', 'customfield_11803', 'customfield_11805', 'customfield_11806', 'customfield_11808', 'customfield_11810', 'customfield_11811', 'customfield_11812', 'customfield_11900', 'customfield_11901', 'customfield_11902', 'customfield_11903', 'customfield_11905', 'customfield_12000', 'customfield_12001', 'customfield_12002', 'customfield_12003', 'customfield_12004', 'customfield_12005', 'customfield_12006', 'customfield_12007', 'customfield_12008', 'customfield_12009', 'customfield_12015', 'customfield_12016', 'customfield_12017', 'customfield_12018', 'customfield_12020', 'customfield_12021', 'customfield_12022', 'customfield_12023', 'customfield_12024', 'customfield_12025', 'customfield_12026', 'customfield_12027', 'customfield_12028', 'customfield_12029', 'customfield_12030', 'customfield_12031', 'customfield_12032', 'customfield_12033', 'customfield_12034', 'customfield_12035', 'customfield_12036', 'customfield_12037', 'customfield_12038', 'customfield_12039', 'customfield_12100', 'customfield_12102', 'customfield_12103', 'customfield_12105', 'customfield_12106', 'customfield_12107', 'customfield_12200', 'customfield_12204', 'customfield_12206', 'customfield_12207', 'customfield_12208', 'customfield_12209', 'customfield_12210', 'customfield_12300', 'customfield_12400', 'customfield_12401', 'customfield_12402', 'customfield_12404', 'customfield_12405', 'customfield_12406', 'customfield_12407', 'customfield_12500', 'customfield_12501', 'customfield_12503', 'customfield_12504', 'customfield_12506', 'customfield_12507', 'customfield_12508', 'customfield_12509', 'customfield_12512', 'customfield_12514', 'customfield_12517', 'customfield_12518', 'customfield_12519', 'customfield_12521', 'customfield_12523', 'customfield_12525', 'customfield_12600', 'customfield_12601', 'customfield_12603', 'customfield_12604', 'customfield_12606', 'customfield_12609', 'customfield_12610', 'customfield_12612', 'customfield_12613', 'customfield_12614', 'customfield_12616', 'customfield_12617', 'customfield_12618', 'customfield_12619', 'customfield_12620', 'customfield_12621', 'customfield_12625', 'customfield_12627', 'customfield_12628', 'customfield_12629', 'customfield_12630', 'customfield_12631', 'customfield_12632', 'customfield_12633', 'customfield_12638', 'customfield_12639', 'customfield_12700', 'customfield_12900', 'customfield_12901', 'customfield_12902', 'customfield_12903', 'description', 'duedate', 'environment', 'fixVersions', 'issuelinks', 'issuetype', 'labels', 'lastViewed', 'priority', 'progress', 'project', 'reporter', 'resolution', 'resolutiondate', 'status', 'subtasks', 'summary', 'timeestimate', 'timeoriginalestimate', 'timespent', 'updated', 'versions', 'votes', 'watches', 'workratio']

可以看到这里面有很多的自定义字段,这些感兴趣的可以继续dir()下去。除了自定义的属性外,可以看到issue中的属性:

'assignee', 'components', 'created', 'creator','description', 'duedate', 'environment', 'fixVersions', 'issuelinks', 'issuetype', 'labels', 'lastViewed', 'priority', 'progress', 'project', 'reporter', 'resolution', 'resolutiondate', 'status', 'subtasks', 'summary', 'timeestimate', 'timeoriginalestimate', 'timespent', 'updated', 'versions', 'votes', 'watches', 'workratio'

使用以下方法打印属性:

print(issue.fields.assignee)
print(issue.fields.created)

爱吃鱼的猫
2020-02-26T12:53:47.000+0800

这样就拿到了我们想要的属性了。