gpt4 book ai didi

Python 包构建 - 导入函数以在类定义中使用

转载 作者:行者123 更新时间:2023-11-30 23:08:56 25 4
gpt4 key购买 nike

我正在构建一个 python 包,它基本上是请求包的包装器,旨在使对一组数据库的各种 api 调用更容易。

目前,我的包具有以下目录结构:

package\
- __init__.py
- coreFunc.py
subpackage\
- __init__.py
- mod1.py
- mod2.py

该包的主要功能位于 mod1.pymod2.py 中。 mod1.py 看起来像这样:

import requests as _requests
from package.coreFunc import __func1

class DataPull:
def __init__(self, arg1):
self._url = "http://www.somesite.com/info?"
self._api_param = {'argument':__func1(arg1)}
self._pull = _requests.get(self._url, params = self._api_param)
def DataTableOne(self):
_headers = self._pull.json()['resultSets'][0]['headers']
_values = self._pull.json()['resultSets'][0]['rowSet']
return [dict(zip(_headers, value)) for value in _values]
def DataTableTwo(self):
_headers = self._pull.json()['resultSets'][1]['headers']
_values = self._pull.json()['resultSets'][1]['rowSet']
return [dict(zip(_headers, value)) for value in _values]

coreFunc.py 中,我需要在 mod1.pymod2.py 中的特定类中使用一些函数。事实上,在类定义的第三行中,我使用 coreFunc 中定义的函数 (__func1) 来修改用户输入的参数以确保正确的值被传递到 api 调用。

coreFunc.py 看起来像这样:

def __func1(x):
if str(x) == "1999":
return "1999-00"
elif len(str(x)) == 4:
try:
return "-".join([str(x),str(int(x) % 100 + 1)])
except:
raise Exception("Enter the four-digit year")
else: raise Exception("Enter the four-digit year")

我正在使用一个类来进行此调用,因为该调用会生成多个数据表,并且我正在使用方法来访问每个数据表。

我的问题是,当我尝试创建 DataPull 类的对象时:

newObj = DataPull(argument)

给我以下错误:

---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-24-e3399cf393bd> in <module>()
----> 1 traceback.extract_stack(package.mode1.DataPull("203112"))

C:\Users\Bradley\Anaconda3\lib\site-packages\test-package-py3.4.egg\package\subpackage\mod1.py in __init__(self, arg1)
140 self._url = "http://www.somesite.com/info?"
--> 141 self._api_param = {"Season":__func1(arg1)}

NameError: name '_DataPull__func1' is not defined

如何正确地将 __func1 导入 mod1.py 来修复此错误?

最佳答案

这是name mangling的案例,类定义中前面带有 __ 的任何内容都会更改为 _classname__attr。引用自文档:

Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped. This mangling is done without regard to the syntactic position of the identifier, as long as it occurs within the definition of a class.

这是在源代码级别完成的,因此您可以将类定义中要使用的函数名称更改为其他名称,这样它就可以正常工作。

<小时/>

来自compile.c的相关CPython代码:

PyObject *
_Py_Mangle(PyObject *privateobj, PyObject *ident)
{
/* Name mangling: __private becomes _classname__private.
This is independent from how the name is used. */
const char *p, *name = PyString_AsString(ident);
char *buffer;
size_t nlen, plen;
if (privateobj == NULL || !PyString_Check(privateobj) ||
name == NULL || name[0] != '_' || name[1] != '_') {
Py_INCREF(ident);
return ident;
}
p = PyString_AsString(privateobj);
nlen = strlen(name);
/* Don't mangle __id__ or names with dots.

The only time a name with a dot can occur is when
we are compiling an import statement that has a
package name.

TODO(jhylton): Decide whether we want to support
mangling of the module name, e.g. __M.X.
*/
if ((name[nlen-1] == '_' && name[nlen-2] == '_')
|| strchr(name, '.')) {
Py_INCREF(ident);
return ident; /* Don't mangle __whatever__ */
}
/* Strip leading underscores from class name */
while (*p == '_')
p++;
if (*p == '\0') {
Py_INCREF(ident);
return ident; /* Don't mangle if class is just underscores */
}
plen = strlen(p);

if (plen + nlen >= PY_SSIZE_T_MAX - 1) {
PyErr_SetString(PyExc_OverflowError,
"private identifier too large to be mangled");
return NULL;
}

ident = PyString_FromStringAndSize(NULL, 1 + nlen + plen);
if (!ident)
return 0;
/* ident = "_" + p[:plen] + name # i.e. 1+plen+nlen bytes */
buffer = PyString_AS_STRING(ident);
buffer[0] = '_';
strncpy(buffer+1, p, plen);
strcpy(buffer+1+plen, name);
return ident;
}

关于Python 包构建 - 导入函数以在类定义中使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31465362/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com