Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 减少Dart中包装器对象的数量_Python_Oop_Python 2.7_Dart_Wrapper - Fatal编程技术网

Python 减少Dart中包装器对象的数量

Python 减少Dart中包装器对象的数量,python,oop,python-2.7,dart,wrapper,Python,Oop,Python 2.7,Dart,Wrapper,我的项目涉及将Python 2.7代码转换为Dart代码。为了完全模拟Python数据类型的所有特性,我在Dart中创建了包装器类,它扩展了原始Dart数据类型的功能,以匹配相应的Python类型。所有类型都有包装器,比如$PyNum代表数字,$PyString代表字符串等等。一切正常,翻译后的代码工作正常。因为代码类似于: def fib(n): if n <= 2: return 1 else: return fib (n - 1) +

我的项目涉及将Python 2.7代码转换为Dart代码。为了完全模拟Python数据类型的所有特性,我在Dart中创建了包装器类,它扩展了原始Dart数据类型的功能,以匹配相应的Python类型。所有类型都有包装器,比如$PyNum代表数字,$PyString代表字符串等等。一切正常,翻译后的代码工作正常。因为代码类似于:

def fib(n):
    if n <= 2:
        return 1
    else:
        return fib (n - 1) + fib (n - 2)

print (fib(36))
def fib(n):
如果n个新的$PyNum(_value+other.value());
运算符-(other)=>new$PyNum(_value-other.value());
运算符*(other)=>new$PyNum(_value*other.value());
运算符~/(其他)=>new$PyNum(_value~/other.value());
运算符|(other)=>new$PyNum(_value | other.value());
运算符和(其他)=>new$PyNum(_value&other.value());
运算符^(其他)=>new$PyNum(_value^other.value());
运算符%(其他)=>new$PyNum(_值%other.value());
运算符(其他)=>new$PyNum(_value>>other.value());
运算符==(其他){
开关($getType(其他)){
案例6:
返回_值==其他;
案例5:
返回_value==other.value();
违约:
返回false;
}
}
操作员(其他)=>!(此<其他)和(此!=其他);
运算符(this=(其他)=>(此>其他)| |(此==其他);
}
$getType(变量){
if(变量为bool)
返回0;
else if(变量为$PyBool)
返回1;
else if(变量为$PyDict)
返回2;
else if(变量为$PyList)
返回3;
else if(变量为List)
返回4;
else if(变量为$PyNum)
返回5;
else if(变量为num)
返回6;
else if(变量为$PyString)
返回7;
else if(变量为$PyTuple)
返回8;
其他的
返回-1;
}
可以从这个类中提取常量对象吗?我不太清楚具体怎么做


有没有其他方法可以有效地做到这一点,并且仍然能够模拟Python的所有特性?非常感谢您的帮助

我有一个类似的情况,我需要将附加信息与基本数据类型(如String、int、double等)连接起来
除了包装它们,我没有找到别的解决办法

您可以尝试通过以下方式优化这些包装器类

  • 使它们成为常量(使用常量构造函数
  • 尽可能使字段成为最终字段
  • 其他的也有可能
编辑
-你肯定想摆脱那些switch语句

  • 0.134285秒:无包装

  • 0.645971秒:对于简化的构造函数,运算符我没有尝试过,但是对于Python中需要的任何方法,请不要包装对象,而是将其作为一个独立函数,使用类型大小写来实现。因此,两者之间的任何共同点都将全速运行。仅在一个Python类中实现的方法将是pret您只需要对Python中的巨态进行大量类型测试

    或者用Dart编写一个Python解释器


    即使在您给出的示例中,如果使用const对象而不是每次都分配一个新的PyNum,您可能会做得更好。

    示例代码,其中wrappers的速度要慢6.3倍:

  • 构造函数只包含wrapps值。如果需要conversion,请使用其他方法,例如其他附加构造函数
  • 拆分比较运算符以减少不必要的类型检查
  • 改进了算术运算符,增加了类型检查
  • Python类型组合成$PyType组。这减少了类型检查
  • 从此示例中删除了不必要的代码

    导入'dart:io';
    纤维蛋白原(n){
    if(n stdout.writeln(fib2(新$PyNum(42)));
    }
    void度量值(字符串msg,f()){
    var sw=新秒表();
    sw.start();
    f();
    sw.stop();
    打印(“$msg:${sw.elapsedmillesons}”);
    }
    类$PyTypes{
    静态常量$PyTypes NUM=常量$PyTypes(“NUM”);
    最后的字符串名;
    const$PyTypes(this.name);
    }
    抽象类$PyType{
    $PyTypes获取pyType;
    }
    类$PyNum扩展了$PyType{
    最终整数值;
    $PyTypes get pyType=>$PyTypes.NUM;
    $PyNum(此.value);
    操作员+(其他){
    if(其他为$PyType){
    开关(其他.pyType){
    案例$PyTypes.NUM:
    $PyNum PyNum=其他;
    返回新的$PyNum(value+PyNum.value);
    }
    }else if(其他为int){
    返回新的$PyNum(值+其他);
    }
    抛出新ArgumentError(“其他:$other”);
    }
    操作员-(其他){
    if(其他为$PyType){
    开关(其他.pyType){
    案例$PyTypes.NUM:
    $PyNum PyNum=其他;
    返回新的$PyNum(value-PyNum.value);
    }
    }else if(其他为int){
    返回新的$PyNum(值-其他);
    }
    抛出新ArgumentError(“其他:$other”);
    }
    运算符==(其他){
    if(其他为$PyType){
    开关(其他.pyType){
    案例$PyTypes.NUM:
    $PyNum PyNum=其他;
    返回值==pyNum.value;
    }
    }else if(其他为int){
    返回值==其他;
    }
    抛出新ArgumentError(“其他:$other”);
    }
    
    运算符我已使用我编写的包装类更新了问题。这可以转换为常量构造函数吗?我已使用我编写的包装类更新了问题。这可以转换为常量构造函数吗?我对此表示怀疑,但您可以轻松创建一个单独的常量构造函数,例如fromInt(此._值)但是我必须使_值为final,对吗?它的值在任何数学运算中都会被修改,如果我使它为final,我想这是不可能的?我只是简单地看了一下,但我有一个印象,你为结果创建了一个新对象。我有更多的时间时会仔细看。@Gunther,代码操作符(thisimport 'lib/inbuilts.dart'; import 'dart:io'; fib(n) { if (n <= new $PyNum(2)) { return new $PyNum(1); } else { return (fib((n - new $PyNum(1))) + fib((n - new $PyNum(2)))); } } main() { stdout.writeln(fib(new $PyNum(36))); }
    import'dart:io';
    
    fib(n) {
        if (n <= 2) {
            return 1;
        } else {
            return (fib((n - 1)) + fib((n - 2)));
        }
    }
    
    main() {
        stdout.writeln(fib(36));
    }
    
    class $PyNum {
        num _value;
    
        $PyNum(value) {
            switch ($getType(value)) {
                case 6:
                    _value = value;
                    break;
                case 7:
                    try {
                        _value = num.parse(value);
                    } catch (ex) {
                        print("Invalid string literal for num parsing");
                        exit(1);
                    }
                    break;
                case 5:
                    _value = value.value();
                    break;
                default:
                    throw "Invalid input for num conversion";
            }
        }
    
        value() => _value;
        toString() => _value.toString();
    
        operator +(other) => new $PyNum(_value + other.value());
        operator -(other) => new $PyNum(_value - other.value());
        operator *(other) => new $PyNum(_value * other.value());
        operator ~/(other) => new $PyNum(_value ~/ other.value());
        operator |(other) => new $PyNum(_value | other.value());
        operator &(other) => new $PyNum(_value & other.value());
        operator ^(other) => new $PyNum(_value ^ other.value());
        operator %(other) => new $PyNum(_value % other.value());
        operator <<(other) => new $PyNum(_value << other.value());
        operator >>(other) => new $PyNum(_value >> other.value());
        operator ==(other) {
            switch ($getType(other)) {
                case 6:
                    return _value == other;
                case 5:
                    return _value == other.value();
                default:
                    return false;
            }
        }
        operator <(other) {
            switch ($getType(other)) {
                case 6:
                    return _value < other;
                case 5:
                    return _value < other.value();
                default:
                    return true;
            }
        }
        operator >(other) => !(this < other) && (this != other);
        operator <=(other) => (this < other) || (this == other);
        operator >=(other) => (this > other) || (this == other);
    }
    
    $getType(variable) {
        if (variable is bool)
            return 0;
        else if (variable is $PyBool)
            return 1;
        else if (variable is $PyDict)
            return 2;
        else if (variable is $PyList)
            return 3;
        else if (variable is List)
            return 4;
        else if (variable is $PyNum)
            return 5;
        else if (variable is num)
            return 6;
        else if (variable is $PyString)
            return 7;
        else if (variable is $PyTuple)
            return 8;
        else
            return -1;
    }