首页 \ 问答 \ boost.python避免两次注册内部类,但仍然在python中公开(boost.python Avoid registering inner class twice but still expose in python)

boost.python避免两次注册内部类,但仍然在python中公开(boost.python Avoid registering inner class twice but still expose in python)

我有一些C ++数据结构,其中模板化的外部结构具有内部结构。 根据模板参数,内部结构可能是也可能不是同一类型。 当我使用boost.python将结构暴露给python时,我希望能够将内部类称为Outer.Inner。 在我的boost.python暴露代码中,我应该只暴露每个不同的内部类型一次。 我可以查询boost.python注册表以避免多次暴露同一个内部类,但我该怎么做才能使以前暴露的内部类成为其外部类的属性? 考虑到这个被剥离的例子,问题可能会更清楚:

#include <boost/python.hpp>

struct inner {
};

template< typename T >
struct outer {
    typedef inner inner_t;

    static const char * name();

    static
    void expose() {
        using namespace boost::python;

        class_< outer< T > > outer_class( name() );

        // check if inner type is in registry already
        const type_info inner_info = boost::python::type_id< inner_t >();
        const converter::registration * inner_registration
            = boost::python::converter::registry::query( inner_info );
        if( inner_registration == 0 || inner_registration->m_to_python == 0 ) {
            // not already in registry
            scope outer_scope( outer_class );
            class_< inner_t > inner_class( "Inner" );
        } else {
            // already in registry because exposed via different outer
            // what to put here? In python we need Outer.Inner to exist
        }
    }
};

template<>
const char *
outer< int >::name() { return "IntOuter"; }

template<>
const char *
outer< double >::name() { return "DoubleOuter"; }

BOOST_PYTHON_MODULE( inner_classes )
{
    outer< int >::expose();
    outer< double >::expose();
}

这是我想要运行的python代码:

import inner_classes as IC

IC.IntOuter.Inner
IC.DoubleOuter.Inner

为了完整性,这里有一个Jamroot来编译上面的内容:

import python ;
use-project boost : $(BOOST_ROOT) ;

project : requirements <library>/boost/python//boost_python ;

python-extension inner_classes : inner-classes.cpp ;

install install
  : inner_classes 
  : <install-dependencies>on <install-type>SHARED_LIB <install-type>PYTHON_EXTENSION 
    <location>. 
  ;

local rule run-test ( test-name : sources + )
{
    import testing ;
    testing.make-test run-pyd : $(sources) : : $(test-name) ;
}
run-test test : inner_classes test_inner_classes.py ;

I have some C++ data structures where a templated outer struct has an internal struct. Depending on the template parameter the internal structs may or may not be the same type. When I expose the structures to python using boost.python I want to be able to refer to the inner classes as Outer.Inner. In my boost.python exposing code I should only expose each distinct inner type once. I can query the boost.python registry to avoid exposing the same inner class more than once but what should I do to make a previously exposed inner class an attribute of its outer class? The question might be clearer given this stripped down example:

#include <boost/python.hpp>

struct inner {
};

template< typename T >
struct outer {
    typedef inner inner_t;

    static const char * name();

    static
    void expose() {
        using namespace boost::python;

        class_< outer< T > > outer_class( name() );

        // check if inner type is in registry already
        const type_info inner_info = boost::python::type_id< inner_t >();
        const converter::registration * inner_registration
            = boost::python::converter::registry::query( inner_info );
        if( inner_registration == 0 || inner_registration->m_to_python == 0 ) {
            // not already in registry
            scope outer_scope( outer_class );
            class_< inner_t > inner_class( "Inner" );
        } else {
            // already in registry because exposed via different outer
            // what to put here? In python we need Outer.Inner to exist
        }
    }
};

template<>
const char *
outer< int >::name() { return "IntOuter"; }

template<>
const char *
outer< double >::name() { return "DoubleOuter"; }

BOOST_PYTHON_MODULE( inner_classes )
{
    outer< int >::expose();
    outer< double >::expose();
}

Here's the python code that I would like to run:

import inner_classes as IC

IC.IntOuter.Inner
IC.DoubleOuter.Inner

For completeness here's a Jamroot to compile the above:

import python ;
use-project boost : $(BOOST_ROOT) ;

project : requirements <library>/boost/python//boost_python ;

python-extension inner_classes : inner-classes.cpp ;

install install
  : inner_classes 
  : <install-dependencies>on <install-type>SHARED_LIB <install-type>PYTHON_EXTENSION 
    <location>. 
  ;

local rule run-test ( test-name : sources + )
{
    import testing ;
    testing.make-test run-pyd : $(sources) : : $(test-name) ;
}
run-test test : inner_classes test_inner_classes.py ;

原文:https://stackoverflow.com/questions/16892966
更新时间:2024-05-02 22:05

最满意答案

一些例子来理解结构。 这些都意味着相同(差异很小):

# just a hash
%hash = ( 'a', 1, 'b', '2' );
%hash = ( a => 1, b => '2' );
# ref to hash
$hash_ref = \%hash;
$hash_ref = { a => 1, b => 2 };

print $hash{ a }; #prints 1
print $hash_ref->{ a }; #prints 1

1和'2'是值。 价值观可能只是标量。 对SOMETHING的引用也是标量。 上例中的$ hash_ref。

在您的示例中,您说第一个哈希是列表。 我认为你的意思是数组:

$list = [ $error1, $error2 ];

$error1 = { error_name => $description }

$description = { status => 'status', message => 'msg', params => [ 1,2,'asdf'] }

你知道一个子获取标量列表。 如果要将哈希传递给sub,则只需传递对此哈希的引用

fn( \%hash );

并在sub获取此哈希:

sub fn { 
    my( $hash ) =  @_;
    print $hash->{ key_name };
}

我想你只有一个错误列表,每个错误包含键:

$list_of_errors = [
    { status => 1, message => 'hello' },
    { status => 2, message => 'hello2' },
    { status => 1, message => 'hello3' },
] 

fn( $list_of_errors );

sub fn {
   my( $le ) =  @_;

   print $le->[1]{ message }; #will print 'hello2'
   # print $le->{ error_name }{ status }; #try this in case hash of hashes
}

要更好地理解结构,请尝试使用Data :: Dump模块;

use Data::Dump qw/ pp /;
%hash = ( a => 1 );
$hash = \%hash;
$arr =  [ 1, 2, 'a' ];
print pp $hash, \%hash, $arr;

祝你好运。

our %error = (
    ERROR_1 => {
         statusCode => 561,
         message => "an unexpected error occurred at location X",
         params => $param_1,
    },
    ERROR_2 => {
         statusCode => 561,
         message => "an unexpected error occurred at location Y",
         params => $param_1,
   }
);

sub print_err {
    my( $err_name ) =  @_;

    print $error{ $err_name }{ message } ."\n";
}

print_err( 'ERROR_1' );
print_err( 'ERROR_2' );

Some examples to understand structures. These all mean same (with small difference):

# just a hash
%hash = ( 'a', 1, 'b', '2' );
%hash = ( a => 1, b => '2' );
# ref to hash
$hash_ref = \%hash;
$hash_ref = { a => 1, b => 2 };

print $hash{ a }; #prints 1
print $hash_ref->{ a }; #prints 1

1 and '2' are values. Values maybe only scalars. Reference to SOMETHING is also scalar. $hash_ref in the example above.

In your example you say 1st hash is list. I think you mean array:

$list = [ $error1, $error2 ];

$error1 = { error_name => $description }

$description = { status => 'status', message => 'msg', params => [ 1,2,'asdf'] }

You know that a sub get list of scalars. If you want to pass hash into sub you just pass reference to this hash

fn( \%hash );

and get this hash at sub:

sub fn { 
    my( $hash ) =  @_;
    print $hash->{ key_name };
}

I suppose you have just a list of errors, each of them contain keys:

$list_of_errors = [
    { status => 1, message => 'hello' },
    { status => 2, message => 'hello2' },
    { status => 1, message => 'hello3' },
] 

fn( $list_of_errors );

sub fn {
   my( $le ) =  @_;

   print $le->[1]{ message }; #will print 'hello2'
   # print $le->{ error_name }{ status }; #try this in case hash of hashes
}

To understand structures better try to use Data::Dump module;

use Data::Dump qw/ pp /;
%hash = ( a => 1 );
$hash = \%hash;
$arr =  [ 1, 2, 'a' ];
print pp $hash, \%hash, $arr;

Good luck.

CODE

our %error = (
    ERROR_1 => {
         statusCode => 561,
         message => "an unexpected error occurred at location X",
         params => $param_1,
    },
    ERROR_2 => {
         statusCode => 561,
         message => "an unexpected error occurred at location Y",
         params => $param_1,
   }
);

sub print_err {
    my( $err_name ) =  @_;

    print $error{ $err_name }{ message } ."\n";
}

print_err( 'ERROR_1' );
print_err( 'ERROR_2' );

相关问答

更多

相关文章

更多

最新问答

更多
  • sp_updatestats是否导致SQL Server 2005中无法访问表?(Does sp_updatestats cause tables to be inaccessible in SQL Server 2005?)
  • 如何创建一个可以与持续运行的服务交互的CLI,类似于MySQL的shell?(How to create a CLI that can interact with a continuously running service, similar to MySQL's shell?)
  • AESGCM解密失败的MAC(AESGCM decryption failing with MAC)
  • Zurb Foundation 4 - 嵌套网格对齐问题(Zurb Foundation 4 - Nested grid alignment issues)
  • 湖北京山哪里有修平板计算机的
  • SimplePie问题(SimplePie Problem)
  • 在不同的任务中,我们可以同时使用多少“上下文”?(How many 'context' we can use at a time simultaneously in different tasks?)
  • HTML / Javascript:从子目录启用文件夹访问(HTML/Javascript: Enabling folder access from a subdirectory)
  • 为什么我会收到链接错误?(Why do I get a linker error?)
  • 如何正确定义析构函数(How to properly define destructor)
  • 垂直切换菜单打开第3级父级。(Vertical toggle menu 3rd level parent stay opened. jQuery)
  • 类型不匹配 - JavaScript(Type mismatch - JavaScript)
  • 为什么当我将模型传递给我的.Net MVC 4控制器操作时,它坚持在部分更新中使用它?(Why is it that when I pass a Model to my .Net MVC 4 Controller Action it insists on using it in the Partial Update?)
  • 在使用熊猫和statsmodels时拉取变量名称(Pulling variable names when using pandas and statsmodels)
  • 如何开启mysql计划事件
  • 检查数组的总和是否大于最大数,反之亦然javascript(checking if sum of array is greater than max number and vice versa javascript)
  • 使用OpenGL ES绘制轮廓(Drawing Outline with OpenGL ES)
  • java日历格式(java Calendar format)
  • Python PANDAS:将pandas / numpy转换为dask数据框/数组(Python PANDAS: Converting from pandas/numpy to dask dataframe/array)
  • 如何搜索附加在elasticsearch索引中的文档的内容(How to search a content of a document attached in elasticsearch index)
  • LinQ to Entities:做相反的查询(LinQ to Entities: Doing the opposite query)
  • 从ExtJs 4.1商店中删除记录时会触发哪些事件(Which events get fired when a record is removed from ExtJs 4.1 store)
  • 运行javascript后如何截取网页截图[关闭](How to take screenshot of a webpage after running javascript [closed])
  • 如何使用GlassFish打印完整的堆栈跟踪?(How can I print the full stack trace with GlassFish?)
  • 如何获取某个exe应用程序的出站HTTP请求?(how to get the outbound HTTP request of a certain exe application?)
  • 嗨,Android重叠背景片段和膨胀异常(Hi, Android overlapping background fragment and inflate exception)
  • Assimp详细说明typedef(Assimp elaborated type refers to typedef)
  • 初始化继承类中不同对象的列表(initialize list of different objects in inherited class)
  • 使用jquery ajax在gridview行中保存星级评分(Save star rating in a gridview row using jquery ajax)
  • Geoxml3 groundOverlay zIndex(Geoxml3 groundOverlay zIndex)