在 python 中使用另一个类的类和类方法
我在 jira.py 中有几个类,
class JiraCommand:
name = "<default>"
aliases = []
summary = "<--- no summary --->"
usage = ""
mandatory = ""
commands = None
def __init__(self, commands):
self.commands = commands
def dispatch(self, logger, jira_env, args):
"""Return the exit code of the whole process"""
if len(args) > 0 and args[0] in ("--help", "-h"):
logger.info("")
alias_text = ''
first_alias = True
for a in self.aliases:
if first_alias:
if len(self.aliases) == 1:
alias_text = " (alias: " + a
else:
alias_text = " (aliases: " + a
first_alias = False
else:
alias_text += ", " + a
if not first_alias:
alias_text += ")"
logger.info("%s: %s%s" % (self.name, self.summary, alias_text))
if self.usage == "":
opts = ""
else:
opts = " [options]"
logger.info("")
logger.info("Usage: %s %s %s%s" % \
(sys.argv[0], self.name, self.mandatory, opts))
logger.info(self.usage)
return 0
results = self.run(logger, jira_env, args)
if results:
return self.render(logger, jira_env, args, results)
else:
return 1
def run(self, logger, jira_env, args):
"""Return a non-zero object for success"""
return 0
def render(self, logger, jira_env, args, results):
"""Return 0 for success"""
return 0
在同一个文件“jira.py”中提供了 2 个示例和第二个类
class JiraCat(JiraCommand):
name = "cat"
summary = "Show all the fields in an issue"
usage = """
<issue key> Issue identifier, e.g. CA-1234
"""
def run(self, logger, jira_env, args):
global soap, auth
if len(args) != 1:
logger.error(self.usage)
return 0
issueKey = args[0]
try:
jira_env['fieldnames'] = soap.service.getFieldsForEdit(auth, issueKey)
except Exception, e:
# In case we don't have edit permission
jira_env['fieldnames'] = {}
try:
return soap.service.getIssue(auth, issueKey)
except Exception, e:
logger.error(decode(e))
def render(self, logger, jira_env, args, results):
# For available field names, see the variables in
# src/java/com/atlassian/jira/rpc/soap/beans/RemoteIssue.java
fields = jira_env['fieldnames']
for f in ['key','summary','reporter','assignee','description',
'environment','project',
'votes'
]:
logger.info(getName(f, fields) + ': ' + encode(results[f]))
logger.info('Type: ' + getName(results['type'], jira_env['types']))
logger.info('Status: ' + getName(results['status'], jira_env['statuses']))
logger.info('Priority: ' + getName(results['priority'], jira_env['priorities']))
logger.info('Resolution: ' + getName(results['resolution'], jira_env['resolutions']))
for f in ['created', 'updated',
'duedate'
]:
logger.info(getName(f, fields) + ': ' + dateStr(results[f]))
for f in results['components']:
logger.info(getName('components', fields) + ': ' + encode(f['name']))
for f in results['affectsVersions']:
logger.info(getName('versions', fields) + ': ' + encode(f['name']))
for f in results['fixVersions']:
logger.info('Fix Version/s:' + encode(f['name']))
# TODO bug in JIRA api - attachmentNames are not returned
#logger.info(str(results['attachmentNames']))
# TODO restrict some of the fields that are shown here
for f in results['customFieldValues']:
fieldName = str(f['customfieldId'])
for v in f['values']:
logger.info(getName(fieldName, fields) + ': ' + encode(v))
return 0
现在,JiraCat 使用 JiraCommand 作为参数
我如何使用 JiraCat 来获取实时结果,
这是我尝试过的:
>>> from jira import JiraCommand
>>> dir(JiraCommand)
['__doc__', '__init__', '__module__', 'aliases', 'commands', 'dispatch', 'mandatory', 'name', 'render', 'run', 'summary', 'usage']
>>> jcmd = JiraCommand("http://jira.server.com:8080")
>>> from jira import JiraCat
>>> dir(JiraCat)
['__doc__', '__init__', '__module__', 'aliases', 'commands', 'dispatch', 'mandatory', 'name', 'render', 'run', 'summary', 'usage']
>>> jc = JiraCat(jcmd)
>>> print jc
<jira.JiraCat instance at 0x2356d88>
>>> jc.run("-s", "cat", "QA-65")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "jira.py", line 163, in run
logger.error(self.usage)
AttributeError: 'str' object has no attribute 'error'
I have couple of classes in jira.py, providing 2 for sample
class JiraCommand:
name = "<default>"
aliases = []
summary = "<--- no summary --->"
usage = ""
mandatory = ""
commands = None
def __init__(self, commands):
self.commands = commands
def dispatch(self, logger, jira_env, args):
"""Return the exit code of the whole process"""
if len(args) > 0 and args[0] in ("--help", "-h"):
logger.info("")
alias_text = ''
first_alias = True
for a in self.aliases:
if first_alias:
if len(self.aliases) == 1:
alias_text = " (alias: " + a
else:
alias_text = " (aliases: " + a
first_alias = False
else:
alias_text += ", " + a
if not first_alias:
alias_text += ")"
logger.info("%s: %s%s" % (self.name, self.summary, alias_text))
if self.usage == "":
opts = ""
else:
opts = " [options]"
logger.info("")
logger.info("Usage: %s %s %s%s" % \
(sys.argv[0], self.name, self.mandatory, opts))
logger.info(self.usage)
return 0
results = self.run(logger, jira_env, args)
if results:
return self.render(logger, jira_env, args, results)
else:
return 1
def run(self, logger, jira_env, args):
"""Return a non-zero object for success"""
return 0
def render(self, logger, jira_env, args, results):
"""Return 0 for success"""
return 0
and a second class in the same file "jira.py"
class JiraCat(JiraCommand):
name = "cat"
summary = "Show all the fields in an issue"
usage = """
<issue key> Issue identifier, e.g. CA-1234
"""
def run(self, logger, jira_env, args):
global soap, auth
if len(args) != 1:
logger.error(self.usage)
return 0
issueKey = args[0]
try:
jira_env['fieldnames'] = soap.service.getFieldsForEdit(auth, issueKey)
except Exception, e:
# In case we don't have edit permission
jira_env['fieldnames'] = {}
try:
return soap.service.getIssue(auth, issueKey)
except Exception, e:
logger.error(decode(e))
def render(self, logger, jira_env, args, results):
# For available field names, see the variables in
# src/java/com/atlassian/jira/rpc/soap/beans/RemoteIssue.java
fields = jira_env['fieldnames']
for f in ['key','summary','reporter','assignee','description',
'environment','project',
'votes'
]:
logger.info(getName(f, fields) + ': ' + encode(results[f]))
logger.info('Type: ' + getName(results['type'], jira_env['types']))
logger.info('Status: ' + getName(results['status'], jira_env['statuses']))
logger.info('Priority: ' + getName(results['priority'], jira_env['priorities']))
logger.info('Resolution: ' + getName(results['resolution'], jira_env['resolutions']))
for f in ['created', 'updated',
'duedate'
]:
logger.info(getName(f, fields) + ': ' + dateStr(results[f]))
for f in results['components']:
logger.info(getName('components', fields) + ': ' + encode(f['name']))
for f in results['affectsVersions']:
logger.info(getName('versions', fields) + ': ' + encode(f['name']))
for f in results['fixVersions']:
logger.info('Fix Version/s:' + encode(f['name']))
# TODO bug in JIRA api - attachmentNames are not returned
#logger.info(str(results['attachmentNames']))
# TODO restrict some of the fields that are shown here
for f in results['customFieldValues']:
fieldName = str(f['customfieldId'])
for v in f['values']:
logger.info(getName(fieldName, fields) + ': ' + encode(v))
return 0
Now, JiraCat is using JiraCommand as an argument
How can i use JiraCat to get live results
here is what i tried:
>>> from jira import JiraCommand
>>> dir(JiraCommand)
['__doc__', '__init__', '__module__', 'aliases', 'commands', 'dispatch', 'mandatory', 'name', 'render', 'run', 'summary', 'usage']
>>> jcmd = JiraCommand("http://jira.server.com:8080")
>>> from jira import JiraCat
>>> dir(JiraCat)
['__doc__', '__init__', '__module__', 'aliases', 'commands', 'dispatch', 'mandatory', 'name', 'render', 'run', 'summary', 'usage']
>>> jc = JiraCat(jcmd)
>>> print jc
<jira.JiraCat instance at 0x2356d88>
>>> jc.run("-s", "cat", "QA-65")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "jira.py", line 163, in run
logger.error(self.usage)
AttributeError: 'str' object has no attribute 'error'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
唐卡利斯托说得对。
JiraCat的run方法接受三个参数(logger、jira_env、args);第一个应该是记录器对象,但您传递的是字符串(“-s”)。
因此,报告字符串的错误 (logger="-s") 没有“error”属性就是这样的意思。
您对命令行的评论 (subprocess.Popen(['python', 'jira', '-s', 'jira.server.com:8080';, 'catall', 'JIRA-65'])) 不是与使用相同参数调用 run() 方法相同。看一下 jira.py 的底部,看看它对 sys.argv 做了什么...
编辑 (1):
阅读代码后,以下 python 应该复制您的命令行调用。它有点复杂,并且错过了 jira.py 本身的所有异常处理和逻辑,这可能会变得不稳定,我无法在这里测试它。
DonCallisto has got it right.
JiraCat's run method takes three arguments (logger, jira_env, args); the first one is supposed to be a logger object but you're passing a string ("-s").
So the error that reports a string (logger="-s") has no "error" attribute means just that.
Your comment about the command line (subprocess.Popen(['python', 'jira', '-s', 'jira.server.com:8080';, 'catall', 'JIRA-65'])) is not the same as calling the run() method with the same arguments. Have a look at the bottom of jira.py and see what it does with sys.argv...
Edit (1):
Having read the code, the following python should replicate your command line call. It's a bit complicated, and misses out all the exception handling and logic in jira.py itself, which could get flaky, and I can't test it here.