Python 减少Dart中包装器对象的数量
我的项目涉及将Python 2.7代码转换为Dart代码。为了完全模拟Python数据类型的所有特性,我在Dart中创建了包装器类,它扩展了原始Dart数据类型的功能,以匹配相应的Python类型。所有类型都有包装器,比如$PyNum代表数字,$PyString代表字符串等等。一切正常,翻译后的代码工作正常。因为代码类似于: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) +
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语句
即使在您给出的示例中,如果使用const对象而不是每次都分配一个新的PyNum,您可能会做得更好。示例代码,其中wrappers的速度要慢6.3倍:
导入'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;
}