编程语言
首页 > 编程语言> > Python / C:一次解析所有值以返回Python?

Python / C:一次解析所有值以返回Python?

作者:互联网

如果你在Python中输出很多从C到dict的值,那么有更好的(更快且更不容易出错)的方法吗:

    return Py_BuildValue("{s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:(i,i,i,i),s:(i,i,i,i),s:(i,i,i,i)}",
            "jd\0",             spa.jd, //Julian day
            "jc\0",             spa.jc, //Julian century
            "jde\0",            spa.jde, //Julian ephemeris day
            "jce\0",            spa.jce, //Julian ephemeris century
            "jme\0",            spa.jme, //Julian ephemeris millennium
            "l\0",              spa.l, //earth heliocentric longitude [degrees]
            "b\0",              spa.b, //earth heliocentric latitude [degrees]
            "r\0",              spa.r,     //earth radius vector [Astronomical Units, AU]
            "theta\0",          spa.theta, //geocentric longitude [degrees]
            "beta\0",           spa.beta, //geocentric latitude [degrees]
            "x0\0",             spa.x0, //mean elongation (moon-sun) [degrees]
            "x1\0",             spa.x1, //mean anomaly (sun) [degrees]
            "x2\0",             spa.x2, //mean anomaly (moon) [degrees]
            "x3\0",             spa.x3, //argument latitude (moon) [degrees]
            "x4\0",             spa.x4, //ascending longitude (moon) [degrees]
            "del_psi\0",        spa.del_psi, //nutation longitude [degrees]
            "del_epsilon\0",    spa.del_epsilon, //nutation obliquity [degrees]
            "epsilon0\0",       spa.epsilon0, //ecliptic mean obliquity [arc seconds]
            "epsilon\0",        spa.epsilon, //ecliptic true obliquity  [degrees]
            "del_tau\0",        spa.del_tau, //aberration correction [degrees]
            "lamda\0",          spa.lamda, //apparent sun longitude [degrees]
            "nu0\0",            spa.nu0, //Greenwich mean sidereal time [degrees]
            "nu\0",             spa.nu, //Greenwich sidereal time [degrees]
            "alpha\0",          spa.alpha, //geocentric sun right ascension [degrees]
            "delta\0",          spa.delta, //geocentric sun declination [degrees]
            "h\0",              spa.h, //observer hour angle [degrees]
            "xi\0",             spa.xi, //sun equatorial horizontal parallax [degrees]
            "del_alpha\0",      spa.del_alpha, //sun right ascension parallax [degrees]
            "delta_prime\0",    spa.delta_prime, //topocentric sun declination [degrees]
            "alpha_prime\0",    spa.alpha_prime, //topocentric sun right ascension [degrees]
            "h_prime\0",        spa.h_prime, //topocentric local hour angle [degrees],
            "h0_prime\0",       spa.h0_prime,
            "delta_zero\0",     spa.delta_zero,
            "e0\0",             spa.e0, //topocentric elevation angle (uncorrected) [degrees]
            "del_e\0",          spa.del_e, //atmospheric refraction correction [degrees]
            "e\0",              spa.e, //topocentric elevation angle (corrected) [degrees]
            "eot\0",            spa.eot, //equation of time [minutes]
            "srha\0",           spa.srha, //sunrise hour angle [degrees]
            "ssha\0",           spa.ssha, //sunset hour angle [degrees]
            "sta\0",            spa.sta, //sun transit altitude [degrees]
            "zenith\0",         spa.zenith, //topocentric zenith angle [degrees]
            "azimuth180\0",     spa.azimuth180, //topocentric azimuth angle (westward from south) [-180 to 180 degrees]
            "azimuth\0",        spa.azimuth, //topocentric azimuth angle (eastward from north) [   0 to 360 degrees]
            "incidence\0",      spa.incidence, //surface incidence angle [degrees]
            "_suntransit\0",    spa.suntransit, //local sun transit time (or solar noon) [fractional hour]
            "_sunrise\0",       spa.sunrise, //local sunrise time (+/- 30 seconds) [fractional hour]
            "_sunset\0",        spa.sunset, //local sunset time (+/- 30 seconds) [fractional hour]
            "sunrise\0",        sunrise_hour, sunrise_min, sunrise_sec, sunrise_microsec,
            "sunset\0",         sunset_hour, sunset_min, sunset_sec, sunset_microsec,
            "noon\0",           transit_hour, transit_min, transit_sec, transit_microsec
            );

解决方法:

我同意@Martinv.Löwis关于使用C预处理器及其宏功能来减轻设置和维护类似于你所做的事情的一些负担.如果您正确定义这些宏,则可以安排将所有定义信息放在单个头文件中的单个位置,并避免重复自己.

基本上,您需要有关每个项目或关键字的两条信息.要进入您正在构建的字典中的值对.一件是放在Py_BuildValue()的格式字符串参数中的内容,第二件是键的源和关联值.

您可以通过定义然后重新定义任务所需的宏来提取这两组信息中的每一组.对于您的示例,可以创建以下头文件.注意如何定义两组不同的宏,具体取决于在#included时是否定义了FORMAT或FIELDS.

// builddict.h -- for defining Py_BuildValue() arguments

// define apppropriate macros for current usage
#ifdef FORMAT
    #define SPA_FIELD_LAST(FIELD)           "s:d"
    #define SPA_FIELD(FIELD)                SPA_FIELD_LAST(FIELD)", "
    #define TIME_FIELD_LAST(NAME)           "s:(i,i,i,i)"
    #define TIME_FIELD(NAME)                TIME_FIELD_LAST(NAME)", "
    #define TIME_KEY_FIELD_LAST(KEY,NAME)   "s:(i,i,i,i)"
    #define TIME_KEY_FIELD(KEY,NAME)        TIME_KEY_FIELD_LAST(KEY,NAME)", "
    #undef FORMAT
#elif defined FIELDS
    #define SPA_FIELD_LAST(FIELD)           #FIELD, spa.FIELD
    #define SPA_FIELD(FIELD)                SPA_FIELD_LAST(FIELD),
    #define TIME_FIELD_LAST(NAME)           #NAME, NAME##_hour, NAME##_min, NAME##_sec, NAME##_microsec
    #define TIME_FIELD(NAME)                TIME_FIELD_LAST(NAME),
    #define TIME_KEY_FIELD_LAST(KEY,NAME)   #KEY, NAME##_hour, NAME##_min, NAME##_sec, NAME##_microsec
    #define TIME_KEY_FIELD(KEY,NAME)        TIME_KEY_FIELD_LAST(KEY,NAME),
    #undef FIELDS
#else
    #error neither FORMAT nor FIELDS usage macros are defined
#endif

SPA_FIELD(jd)               // Julian day
SPA_FIELD(jc)               // Julian century
SPA_FIELD(jde)              // Julian ephemeris day
SPA_FIELD(jce)              // Julian ephemeris century
SPA_FIELD(jme)              // Julian ephemeris millennium
SPA_FIELD(l)                // earth heliocentric longitude [degrees]
SPA_FIELD(b)                // earth heliocentric latitude [degrees]
SPA_FIELD(r)                // earth radius vector [Astronomical Units)  AU]
SPA_FIELD(theta)            // geocentric longitude [degrees]
SPA_FIELD(beta)             // geocentric latitude [degrees]
SPA_FIELD(x0)               // mean elongation (moon-sun) [degrees]
SPA_FIELD(x1)               // mean anomaly (sun) [degrees]
SPA_FIELD(x2)               // mean anomaly (moon) [degrees]
SPA_FIELD(x3)               // argument latitude (moon) [degrees]
SPA_FIELD(x4)               // ascending longitude (moon) [degrees]
SPA_FIELD(del_psi)          // nutation longitude [degrees]
SPA_FIELD(del_epsilon)      // nutation obliquity [degrees]
SPA_FIELD(epsilon0)         // ecliptic mean obliquity [arc seconds]
SPA_FIELD(epsilon)          // ecliptic true obliquity  [degrees]
SPA_FIELD(del_tau)          // aberration correction [degrees]
SPA_FIELD(lamda)            // apparent sun longitude [degrees]
SPA_FIELD(nu0)              // Greenwich mean sidereal time [degrees]
SPA_FIELD(nu)               // Greenwich sidereal time [degrees]
SPA_FIELD(alpha)            // geocentric sun right ascension [degrees]
SPA_FIELD(delta)            // geocentric sun declination [degrees]
SPA_FIELD(h)                // observer hour angle [degrees]
SPA_FIELD(xi)               // sun equatorial horizontal parallax [degrees]
SPA_FIELD(del_alpha)        // sun right ascension parallax [degrees]
SPA_FIELD(delta_prime)      // topocentric sun declination [degrees]
SPA_FIELD(alpha_prime)      // topocentric sun right ascension [degrees]
SPA_FIELD(h_prime)          // topocentric local hour angle [degrees])
SPA_FIELD(h0_prime)
SPA_FIELD(delta_zero)
SPA_FIELD(e0)               // topocentric elevation angle (uncorrected) [degrees]
SPA_FIELD(del_e)            // atmospheric refraction correction [degrees]
SPA_FIELD(e)                // topocentric elevation angle (corrected) [degrees]
SPA_FIELD(eot)              // equation of time [minutes]
SPA_FIELD(srha)             // sunrise hour angle [degrees]
SPA_FIELD(ssha)             // sunset hour angle [degrees]
SPA_FIELD(sta)              // sun transit altitude [degrees]
SPA_FIELD(zenith)           // topocentric zenith angle [degrees]
SPA_FIELD(azimuth180)       // topocentric azimuth angle (westward from south) [-180 to 180 degrees]
SPA_FIELD(azimuth)          // topocentric azimuth angle (eastward from north) [   0 to 360 degrees]
SPA_FIELD(incidence)        // surface incidence angle [degrees]
SPA_FIELD(suntransit)       // local sun transit time (or solar noon) [fractional hour]
SPA_FIELD(sunrise)          // local sunrise time (+/- 30 seconds) [fractional hour]
SPA_FIELD(sunset)           // local sunset time (+/- 30 seconds) [fractional hour]
TIME_FIELD(sunrise)
TIME_FIELD(sunset)
TIME_KEY_FIELD_LAST(noon, transit)  // must use a xxx_LAST macro on last one

// clean up to prevent warnings about redefining macros
#undef SPA_FIELD_LAST
#undef SPA_FIELD
#undef TIME_FIELD_LAST
#undef TIME_FIELD
#undef TIME_KEY_FIELD_LAST
#undef TIME_KEY_FIELD

一旦你完成所有设置,你的build_dict()函数变得相当简短,并且与字典的实际内容无关:

// build format string using header
char format_string[] = "{"
    #define FORMAT
    #include "builddict.h"
"}";

// use header again to build list of fields
PyObject* build_dict(SPA spa)
{
    return Py_BuildValue(format_string,
        #define FIELDS
        #include "builddict.h"
    );
}

虽然这并不能完全自动化这个过程,但可以提供很多帮助.可能有其他文本处理或C接口工具可用(或者您可以自己编写)以进一步帮助您创建此单个头文件,因为它采用非常统一的格式.

标签:python,c-3,python-c-extension
来源: https://codeday.me/bug/20190526/1157400.html