主頁 > 軟體工程 > 無法在Pybind11定義的類中分配串列屬性的內容

無法在Pybind11定義的類中分配串列屬性的內容

2022-10-27 13:05:42 軟體工程

我在 C 中有一個稀疏矩陣實作,我使用 pybind11 將它公開給 python。這是問題所在:

>>> D1 = phc.SparseMatrix(3, [[0],[1],[2]])
>>> D1.cData
[[0], [1], [2]]
>>> D1.cData[1] = [1,2]
>>> D1.cData
[[0], [1], [2]] #Should be [[0], [1,2], [2]]

在 python 中,我無法SparseMatrix.cData使用賦值運算子更改屬性的內容。可以用更改整個串列D1.cData = [[1],[2],[3]]這種行為讓我感到困惑。D1.cData只是一個串列,所以我希望上面的代碼可以作業。

我懷疑它與我的 pybind11 代碼有關,因為這種行為在 python 定義的自定義類中不存在。但我不知道出了什么問題(我是新手程式員)。以下是源代碼資訊:

Python 系結

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

namespace py = pybind11;

#include <SparseMatrix.h>

namespace phc = ph_computation;
using SparseMatrix = phc::SparseMatrix;
using Column = phc::Column;
using CData = phc::CData;

PYBIND11_MODULE(ph_computations, m)
{
    m.doc() = "ph_computations python bindings";

    using namespace pybind11::literals;

    m.def("add_cols", &phc::add_cols);//begin SparseMatrix.h

    py::class_<SparseMatrix>(m, "SparseMatrix")
            .def(py::init<size_t, CData>())
            .def(py::init<std::string>())
            .def_readwrite("n_rows", &SparseMatrix::n_rows)
            .def_readwrite("n_cols", &SparseMatrix::n_cols)
            .def_readwrite("cData", &SparseMatrix::cData)
            .def("__neq__", &SparseMatrix::operator!=)
            .def("__eq__", &SparseMatrix::operator==)
            .def("__add__", &SparseMatrix::operator )
            .def("__mul__", &SparseMatrix::operator*)
            .def("transpose", &SparseMatrix::transpose)
            .def("__str__", &SparseMatrix::print)
            .def("save", &SparseMatrix::save)
            ;

    m.def("identity", &phc::make_identity);
    m.def("matching_pivots", &phc::matching_pivots);//end SparseMatrix.h
}

稀疏矩陣.h

#pragma once

#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <iterator>
#include <algorithm>
#include <vector>
#include <stdexcept>

namespace ph_computation{

using Int = int;

using Column = std::vector<Int>;//a Column is represented by a vector of indices
using CData = std::vector<Column>;//a matrix is represented by a vector of Columns

//Add columns in Z2
Column add_cols(const Column& c1, const Column& c2);

struct SparseMatrix
{
    size_t n_rows{0};
    size_t n_cols{0};
    CData cData;

    SparseMatrix()=default;

    SparseMatrix(size_t n_rows_, CData cData_):
    n_rows(n_rows_), n_cols(cData_.size()), cData(cData_){}

    SparseMatrix(std::string path);

    bool operator!=(const SparseMatrix &other) const;

    bool operator==(const SparseMatrix &other) const;

    SparseMatrix operator (const SparseMatrix &other) const;

    SparseMatrix operator*(const SparseMatrix &other) const;

    void transpose();

    void print() const;

    void save(std::string path);
};

SparseMatrix make_identity(size_t n_cols_);

bool matching_pivots(const SparseMatrix& a, const SparseMatrix& b);

}

SparseMatrix.cpp(你可能不需要這個)

#include <SparseMatrix.h>

namespace ph_computation {

Column add_cols(const Column& c1, const Column& c2){
    Column c3;
    int idx1{0};
    int idx2{0};
    while(idx1 < c1.size() && idx2 < c2.size()){
        if(c1[idx1] < c2[idx2]){
            c3.push_back(c1[idx1]);
              idx1;
        }
        else if(c1[idx1] > c2[idx2]){
            c3.push_back(c2[idx2]);
              idx2;
        }
        else {
              idx1;
              idx2;
        }
    }
    if (idx1 < c1.size()){
        c3.insert(c3.end(), std::next(c1.begin(), idx1), c1.end());
    }
    else if (idx2 < c2.size()){
        c3.insert(c3.end(), std::next(c2.begin(), idx2), c2.end());
    }

    return c3;
}

SparseMatrix make_identity(size_t n_cols_){
    CData cData_(n_cols_);
    for (int j = 0; j < n_cols_;   j){
        cData_[j] = {j};
    }
    return SparseMatrix(n_cols_, cData_);
}

SparseMatrix::SparseMatrix(std::string path){
    std::fstream f_in;
    f_in.open(path, std::ios::in);
    if(f_in.is_open()){
        std::string n_rows_line;
        std::getline(f_in, n_rows_line); //first line of file contains number of rows
        n_rows = std::stoi(n_rows_line);

        std::string n_cols_line;
        std::getline(f_in, n_cols_line); //second line of file contains number of cols
        n_cols = std::stoi(n_cols_line);

        CData cData_(n_cols);
        cData = cData_;

        std::string line;
        int j = 0;
        int nnz, data;
        while (std::getline(f_in, line)){
            std::stringstream line_str = std::stringstream(line);
            while (line_str >> nnz){
                Column col_j(nnz);
                for (int i =0; i < nnz;   i){
                    line_str >> data;
                    col_j[i] = data;
                }
                cData[j] = col_j;
            }
              j;
        }
        f_in.close();
    }
    else{
        throw std::runtime_error("File did not open.");
    }
}

bool SparseMatrix::operator!=(const SparseMatrix &other) const{
    if (n_rows != other.n_rows || cData != other.cData){
        return true;
    }
    return false;
}

bool SparseMatrix::operator==(const SparseMatrix &other) const{
    return !(*this != other);
    }

SparseMatrix SparseMatrix::operator (const SparseMatrix &other) const{
        if (n_rows != other.n_rows || n_cols != other.n_cols){
            throw std::invalid_argument("Matrices must have same dimension to add.");
        }

        CData ans_cData;
        for (int j = 0; j < n_cols;   j){
            ans_cData.push_back(add_cols(cData[j], other.cData[j]));
        }

        return SparseMatrix(n_rows, ans_cData);
    }

SparseMatrix SparseMatrix::operator*(const SparseMatrix &other) const{
        if(n_cols != other.n_rows){
            throw std::invalid_argument("Matrices must have compatible dimensions.");
        }

        size_t ans_rows = n_rows;
        CData ans_cData(other.n_cols);
        SparseMatrix ans(ans_rows, ans_cData);

        for(int j =0; j<ans.n_cols;   j){
            for(int idx : other.cData[j]){
                ans.cData[j] = add_cols(ans.cData[j], cData[idx]);
            }
        }

        return ans;
    }

void SparseMatrix::transpose(){
        CData cData_T(n_rows);
        for(int j =0; j<n_cols;   j){
            if(!cData[j].empty()){
                for(int x: cData[j]){
                    cData_T[x].push_back(j);
                }
            }
        }
        cData = cData_T;
        n_rows = n_cols;
        n_cols = cData.size();
    }

void SparseMatrix::print() const{
        for (int i = 0; i < n_rows;   i){
            for (int j = 0; j < n_cols;   j){
                if (cData[j].empty())
                    {std::cout << " 0";}
                else if (std::binary_search(cData[j].begin(), cData[j].end(), i))//Assumes row indices
                    {std::cout << " 1";}                                        //are ordered
                else
                    {std::cout << " 0";}
                if (n_cols-1 == j)
                    {std::cout << " \n";}
            }
        }
    }

void SparseMatrix::save(std::string path){
        std::fstream f_out;
        f_out.open(path, std::ios::out);
        if(f_out.is_open()){
            f_out << n_rows << "\n";
            f_out << n_cols << "\n";
            for(int j = 0; j < n_cols;   j){
                int col_j_sz = cData[j].size();
                f_out << col_j_sz;
                for(int i = 0; i < col_j_sz;   i){
                    f_out << " " << cData[j][i];
                }
                f_out << "\n";
            }
            f_out.close();
        }
        else{
            throw std::runtime_error("File did not open.");
        }
    }

bool matching_pivots(const SparseMatrix& a, const SparseMatrix& b){
    if(a.n_rows != b.n_rows || a.n_cols != b.n_cols){
        throw std::invalid_argument("Input matrices must have the same size.");
    }

    for (int j = 0; j<a.n_cols;   j){
        bool a_j_empty = a.cData[j].empty();
        bool b_j_empty = b.cData[j].empty();
        if (a_j_empty != b_j_empty){
            return false;
        }
        else if (!a_j_empty){
            if(a.cData[j].back() != b.cData[j].back()){
                return false;
            }
        }
    }
    return true;
}

} // namespace ph_computation

uj5u.com熱心網友回復:

我在這里的 pybind11 檔案中找到了答案:https ://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html?highlight=opaque#making-opaque-types

顯然,STL容器資料成員可以在python中被完全覆寫,但是通過串列方法修改資料成員是行不通的。我不太明白,但上面的鏈接回答了這個問題。

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/520997.html

標籤:Pythonc 11赋值运算符pybind11

上一篇:為什么codecvt_utf8將十六進制值作為ffffff附加在開頭?

下一篇:std::generate_n無法生成我的物件

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more