我们应该避免使用C++中的重复代码来成为"Pythonic",以及如何?

hel*_*ker 1 c++ python abstraction repeat hardcoded

我正处于幼虫阶段,使用Python和C++中的预蛋阶段,但我正在尽我所能,特别是"不要重复自己"的原则.

我有一个多通道原始文件格式打开,主要的ascii标头,字段可表示为字符串和整数(总是编码为字符填充白色空格).第二部分是N个头部,其中N是主头部的字段,并且每个头部本身有更多的文本和数字字段(编码为ascii),指的是实际16比特多信道流的长度和大小组成文件的其余部分.

到目前为止,我在C++中有这个工作代码:

#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <map>

using namespace std;

struct Header {
    string version;
    string patinfo;
    string recinfo;
    string start_date;
    string start_time;
    int header_bytes;
    string reserved;
    int nrecs;
    double rec_duration;
    int nchannels;
};

struct Channel {
    string label;
    string transducertype;
    string phys_dim;
    int pmin;
    int pmax;
    int dmin;
    int dmax;
    string prefiltering;
    int n_samples;
    string reserved;
};


int main()
{
    ifstream edf("/home/helton/Dropbox/01MIOTEC/06APNÉIA/Samples/Osas2002plusQRS.rec", ios::binary);

    // prepare to read file header
    Header header;
    char buffer[80];

    // reads header fields into the struct 'header'
    edf.read(buffer, 8);
    header.version = string(buffer, 8);

    edf.read(buffer, 80);
    header.patinfo = string(buffer, 80);

    edf.read(buffer, 80);
    header.recinfo = string(buffer, 80);

    edf.read(buffer, 8);
    header.start_date = string(buffer, 8);

    edf.read(buffer, 8);
    header.start_time = string(buffer, 8);

    edf.read(buffer, 8);
    stringstream(buffer) >> header.header_bytes;

    edf.read(buffer, 44);
    header.reserved = string(buffer, 44);

    edf.read(buffer, 8);
    stringstream(buffer) >> header.nrecs;

    edf.read(buffer,8);
    stringstream(buffer) >> header.rec_duration;

    edf.read(buffer,4);
    stringstream(buffer) >> header.nchannels;

    /*
    cout << "'" << header.version << "'" << endl;
    cout << "'" << header.patinfo << "'" << endl;
    cout << "'" << header.recinfo << "'" << endl;
    cout << "'" << header.start_date << "'" << endl;
    cout << "'" << header.start_time << "'" << endl;
    cout << "'" << header.header_bytes << "'" << endl;
    cout << "'" << header.reserved << "'" << endl;
    cout << "'" << header.nrecs << "'" << endl;
    cout << "'" << header.rec_duration << "'" << endl;
    cout << "'" << header.nchannels << "'" << endl;
    */

    // prepare to read channel headers
    int ns = header.nchannels; // ns tells how much channels I have
    char title[16]; // 16 is the specified length of the "label" field of each channel

    for (int n = 0; n < ns; n++)
    {
        edf >> title;
        cout << title << endl; // and this successfully echoes the label of each channel
    }


    return 0;
};
Run Code Online (Sandbox Code Playgroud)

我必须做的一些评论:

  • 我选择使用struct,因为格式规范非常硬编码;
  • 我没有迭代主头字段,因为我觉得读取的字节和类型的数量相当随意;
  • 现在我成功获得了每个频道的标签,我实际上会为每个频道的字段创建结构,这些字段本身可能必须存储在地图中.

我(希望直截了当)的问题是:

"我是否应该担心偷工减料以使这种代码更加'Pythonic'(更抽象,更少重复),或者这不是C++中的工作方式?"

许多Python福音传教士(就像我自己,因为我喜欢它)突出了它的易用性和所有这些.所以,一段时间以来,我会怀疑我是在做蠢事还是只做正确的事情,但由于C++的本质,我不会那么"自动化".

谢谢阅读

赫尔顿

Fre*_*Foo 5

我会说没有Pythonic C++代码这样的东西.DRY原则适用于两种语言,但许多被认为是"Pythonic"的东西只是使用Python特定结构在Python中表达逻辑的最短,最甜蜜的方式.惯用C++是完全不同的.

lambda例如,有时不被认为是非常Pythonic,并且保留用于没有其他解决方案的情况,但只是被添加到C++标准中.C++没有关键字参数,这些参数非常Pythonic.C++程序员不喜欢构建一个map不必要的时候,而Python程序员可能会dict遇到很多问题,他们只是碰巧使意图比有效的替代方案更清晰.

如果你想保存输入,请使用我之前发布的功能,然后:

header.version = read_field(edf, 8);
header.patinfo = read_field(edf, 80);
Run Code Online (Sandbox Code Playgroud)

这应该可以节省很多行.但是比那些几行更重要的是,你已经实现模块化少量:如何阅读领域,什么阅读领域,现在你的程序的不同部分.