一个代码说明作为我的问题的简介:
import re, inspect, datetime
inspect.getargspec (re.findall)
# =>
# ArgSpec(args = ['pattern', 'string', 'flags'], varargs=None,
# keywords=None, defaults = (0,))
type (datetime.datetime.replace)
# => <type 'method_descriptor'>
inspect.getargspec (datetime.datetime.replace)
# => Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# File "/usr/lib/python2.7/inspect.py", line 816, in getargspec
# raise TypeError('{!r} is not a Python function'.format(func))
# TypeError: <method 'replace' of 'datetime.datetime' objects> is
# not a Python function
看来,对我来说,只有这样,才能找到的签名datetime.datetime.replace
,而我的代码是看它在商务部:date.replace(year, month, day)
。
唯一起作用的内省部分是:
datetime.datetime.replace.__doc__
# => 'Return datetime with new specified fields.'
我检查了Jupyter函数arglist工具提示的工作原理,它们有完全相同的问题,即没有arglist可用于datetime.datetime.replace
。
所以这是问题:
是否仍然可以通过某种方式获取参数列表?也许我可以为其安装C源代码datetime
并通过__file__
属性连接它们?
是否可以<type 'method_descriptor'>
用arglist信息注释a ?在那种情况下,我可以解析链接文档的markdown定义并自动注释内置模块功能。
不,您无法获得更多信息;安装C源代码不会使您轻松访问它们。这是因为用C代码定义的大多数方法实际上并没有公开这些信息。您必须解析出相当隐秘的C代码:
if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
datetime_kws,
&y, &m, &d, &hh, &mm, &ss, &us,
&tzinfo, &fold))
该re.findall()
函数是纯Python函数,因此是自省的。
我说过大多数用C定义的方法,因为从Python 3.4开始,使用新Argument Clinic预处理器的方法将包括一个新__text_signature__
属性,内部inspect._signature_fromstr()
函数可以对其进行解析。这意味着即使对于这种C定义的方法,您也可以内省参数:
>>> import io
>>> import inspect
>>> type(io.BytesIO.read)
<class 'method_descriptor'>
>>> inspect.signature(io.BytesIO.read)
<Signature (self, size=None, /)>
另请参见Python 3.4中用于__signature__和__text_signature__的内容
该datetime
模块尚未收到多少Argument Clinic爱。我们必须耐心等待,或者,如果您真的对此很在意,请提供将模块转换为使用Argument Clinic的补丁。
如果你想看到什么模块都具有支持已经,看看Modules/clinic
子目录包含生成的诊所输出; 对于该datetime
模块,datetime.datetime.now()
目前仅包括在内。该方法定义了一个诊所区:
/*[clinic input]
@classmethod
datetime.datetime.now
tz: object = None
Timezone object.
Returns new datetime object representing current time local to tz.
If no tz is specified, uses local timezone.
[clinic start generated code]*/
static PyObject *
datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
使方法自省:
>>> import datetime
>>> inspect.signature(datetime.datetime.now)
<Signature (tz=None)>
无法将信息直接附加到那些自省的C函数和方法上。他们也不支持属性。
想要支持此类对象的大多数自动完成解决方案都使用单独的数据结构,这些结构中的信息被独立维护(数据不同步的所有固有风险)。其中一些可用于您自己的目的:
Komodo IDE代码情报库(开源,也使用其他编辑器)使用CIX格式对该数据进行编码。您可以下载Python 3目录。不幸的是,你的具体的例子,datetime.replace()
函数签名尚未充实了两种:
<scope doc="Return datetime with new specified fields." ilk="function" name="replace" />
新的Python 3.5类型提示语法还需要知道对象期望的参数类型,为此,需要为无法自省的对象提供存根文件。在Python的typeshed项目提供了这些。这包括datetime
模块的所有参数名称:
class datetime:
# ...
def replace(self, year: int = ..., month: int = ..., day: int = ..., hour: int = ...,
minute: int = ..., second: int = ..., microsecond: int = ..., tzinfo:
Optional[_tzinfo] = None) -> datetime: ...
您必须自己解析这样的文件。不能始终将它们作为尚未定义的存根引用类型导入,而不是使用正向引用:
>>> import importlib.machinery
>>> path = 'stdlib/3/datetime.pyi'
>>> loader = importlib.machinery.SourceFileLoader('datetime', path)
>>> loader.load_module()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<frozen importlib._bootstrap_external>", line 399, in _check_name_wrapper
File "<frozen importlib._bootstrap_external>", line 823, in load_module
File "<frozen importlib._bootstrap_external>", line 682, in load_module
File "<frozen importlib._bootstrap>", line 251, in _load_module_shim
File "<frozen importlib._bootstrap>", line 675, in _load
File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
File "stdlib/3/datetime.pyi", line 12, in <module>
class tzinfo:
File "stdlib/3/datetime.pyi", line 13, in tzinfo
def tzname(self, dt: Optional[datetime]) -> str: ...
NameError: name 'datetime' is not defined
通过使用预定义的模块对象和全局变量,然后迭代名称错误直到导入为止,您也许可以解决该问题。我将其留给读者练习。Mypy和其他类型检查器不会尝试执行代码,它们只是构建AST。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句