Chapter 15:JSON Assignment

本文介绍了如何使用Python的json库进行数据的JSON格式转换,包括数据提取、编码与解码过程,通过实例展示了从URL获取JSON数据并计算评论总数的方法。

写在前面:
编码:把一个Python对象编码转换成Json字符串 json.dumps()
解码:把Json格式字符串解码转换成Python对象 json.loads()

一、Extracting data from JSON

import json
import urllib

lst=list()
url=raw_input('Enter location:')
uh=urllib.urlopen(url)
data=uh.read()
info = json.loads(str(data))

for cont in info['comments']:
    lst.append(int(cont["count"]))
print sum(lst)

注意以下loads()的参数是string而返回的是list。

【多变量输入超前多步预测】基于CNN-BiLSTM的光伏功率预测研究(Matlab代码实现)内容概要:本文介绍了基于CNN-BiLSTM模型的多变量输入超前多步光伏功率预测方法,并提供了Matlab代码实现。该研究结合卷积神经网络(CNN)强大的特征提取能力与双向长短期记忆网络(BiLSTM)对时间序列前后依赖关系的捕捉能力,构建了一个高效的深度学习预测模型。模型输入包含多个影响光伏发电的气象与环境变量,能够实现对未来多个时间步长的光伏功率进行精确预测,适用于复杂多变的实际应用场景。文中详细阐述了数据预处理、模型结构设计、训练流程及实验验证过程,展示了该方法相较于传统模型在预测精度和稳定性方面的优势。; 适合人群:具备一定机器学习和深度学习基础,熟悉Matlab编程,从事新能源预测、电力系统分析或相关领域研究的研发人员与高校研究生。; 使用场景及目标:①应用于光伏电站功率预测系统,提升电网调度的准确性与稳定性;②为可再生能源并网管理、能量存储规划及电力市场交易提供可靠的数据支持;③作为深度学习在时间序列多步预测中的典型案例,用于科研复现与教学参考。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,重点关注数据归一化、CNN特征提取层设计、BiLSTM时序建模及多步预测策略的实现细节,同时可尝试引入更多外部变量或优化网络结构以进一步提升预测性能。
// StorageUtil.ets import preferences from '@ohos.data.preferences'; import common from '@ohos.app.ability.common'; // 定义错误代码枚举 enum StorageErrorCode { PREFERENCES_GET_FAILED = 1001, DATA_SAVE_FAILED = 2001, DATA_READ_FAILED = 2002 } // 自定义存储错误类(使用明确类型) class StorageError extends Error { code: StorageErrorCode; operation: string; originalError: Error | null; // 避免使用 any constructor(code: StorageErrorCode, operation: string, message: string, originalError?: Error) { super(message); this.name = "StorageError"; this.code = code; this.operation = operation; this.originalError = originalError || null; Object.setPrototypeOf(this, StorageError.prototype); } } export class StorageUtil { private static readonly PREFERENCES_NAME: string = 'novelReaderPrefs'; private static readonly KEY_FONT_SIZE: string = 'fontSize'; private static readonly KEY_BRIGHTNESS: string = 'brightness'; private static readonly KEY_LAST_CHAPTER: string = 'lastChapter'; // 获取Preferences实例(使用明确返回类型) private static async getPreferences(context: common.UIAbilityContext): Promise<preferences.Preferences> { try { return await preferences.getPreferences(context, { name: StorageUtil.PREFERENCES_NAME }); } catch (error) { // 类型断言为Error const err = error as Error; console.error(`获取Preferences失败: ${err.message}`); // 使用自定义错误类型 throw new StorageError( StorageErrorCode.PREFERENCES_GET_FAILED, "getPreferences", "Preferences获取失败", err ); } } // 保存字体大小(明确参数类型) static async saveFontSize(context: common.UIAbilityContext, size: number): Promise<void> { try { const prefs = await StorageUtil.getPreferences(context); await prefs.put(StorageUtil.KEY_FONT_SIZE, size); await prefs.flush(); } catch (error) { // 类型检查 if (error instanceof StorageError) { console.error(`存储错误[${error.code}]: ${error.message}`); } else if (error instanceof Error) { console.error(`未知错误: ${error.message}`); } else { console.error("发生未知类型的错误"); } } } // 获取字体大小(明确返回类型) static getFontSize(context: common.UIAbilityContext): number { try { const prefs = preferences.getPreferencesSync(context, { name: StorageUtil.PREFERENCES_NAME }); // 使用类型安全的获取方式 const result: preferences.ValueType = prefs.getSync(StorageUtil.KEY_FONT_SIZE, 16); // 类型检查 if (typeof result === 'number') { return result; } else { console.warn("字体大小配置不是数字类型,使用默认值"); return 16; } } catch (error) { const err = error as Error; console.error(`获取字体大小失败: ${err.message}`); return 16; } } // 保存亮度(使用类型安全的API) static async saveBrightness(context: common.UIAbilityContext, value: number): Promise<void> { try { const prefs = await StorageUtil.getPreferences(context); await prefs.put(StorageUtil.KEY_BRIGHTNESS, value); await prefs.flush(); } catch (error) { const err = error as Error; console.error(`保存亮度失败: ${err.message}`); } } // 获取亮度(使用类型安全的获取) static getBrightness(context: common.UIAbilityContext): number { try { const prefs = preferences.getPreferencesSync(context, { name: StorageUtil.PREFERENCES_NAME }); const result: preferences.ValueType = prefs.getSync(StorageUtil.KEY_BRIGHTNESS, 50); if (typeof result === 'number') { return result; } else { console.warn("亮度配置不是数字类型,使用默认值"); return 50; } } catch (error) { const err = error as Error; console.error(`获取亮度失败: ${err.message}`); return 50; } } // 保存最后阅读章节(符合标准库使用规范) static async saveLastChapter(context: common.UIAbilityContext, chapter: number): Promise<void> { try { const prefs = await StorageUtil.getPreferences(context); await prefs.put(StorageUtil.KEY_LAST_CHAPTER, chapter); await prefs.flush(); } catch (error) { const err = error as Error; console.error(`保存章节失败: ${err.message}`); } } // 获取最后阅读章节(避免使用受限标准库) static getLastChapter(context: common.UIAbilityContext): number { try { const prefs = preferences.getPreferencesSync(context, { name: StorageUtil.PREFERENCES_NAME }); const result: preferences.ValueType = prefs.getSync(StorageUtil.KEY_LAST_CHAPTER, 1); if (typeof result === 'number') { return result; } else { console.warn("章节配置不是数字类型,使用默认值"); return 1; } } catch (error) { const err = error as Error; console.error(`获取章节失败: ${err.message}`); return 1; } } } 报错 Usage of standard library is restricted (arkts-limited-stdlib) <ArkTSCheck>,Prototype assignment is not supported (arkts-no-prototype-assignment) <ArkTSCheck>
06-27
<think>我们遇到了两个ArkTS检查错误:1.`arkts-limited-stdlib`:标准库使用受限。这意味着我们不能使用某些JavaScript标准库函数。2.`arkts-no-prototype-assignment`:不支持原型赋值。在代码中,我们使用了`Object.setPrototypeOf`来设置错误对象的原型,这在ArkTS中是不允许的。解决方案:1.对于`arkts-limited-stdlib`:我们需要确保代码中没有使用受限的标准库函数。例如,避免使用`JSON.stringify`、`Array.prototype.includes`等。在我们的代码中,目前没有明显使用这些函数,但是要注意在错误处理中,我们使用了`console.error`,这个在OpenHarmony中是允许的,所以问题不大。另外,在获取Preferences时,我们使用了`preferences.getPreferences`和`preferences.getPreferencesSync`,这些都是OpenHarmony提供的API,不受此限制。2.对于`arkts-no-prototype-assignment`:在`StorageError`的构造函数中,我们使用了`Object.setPrototypeOf(this,StorageError.prototype);`来确保原型链正确。在ArkTS中,不允许直接修改对象的原型。我们可以通过其他方式来实现继承,例如使用ES6的类继承(使用`extends`),并且避免手动修改原型。实际上,在ES6中,如果我们使用`class`和`extends`,原型链会自动设置好。因此,我们可能不需要手动设置原型。我们可以尝试删除这行代码,看看是否会影响错误捕获。但是,在TypeScript中,当我们自定义错误类并继承`Error`时,有时在转译后的代码中,原型链可能不会正确设置,特别是在一些老版本的环境中。然而,在OpenHarmony的ArkTS环境中,我们使用的是较新的ES标准,所以应该可以安全地移除这行代码。修改步骤:-删除`StorageError`构造函数中的`Object.setPrototypeOf`调用。-确保`StorageError`类正确继承自`Error`,使用`extends`关键字。另外,我们还需要检查整个代码中是否还有其他地方使用了受限的标准库函数或修改原型的操作。修改后的`StorageError`类:```typescriptclassStorageErrorextendsError{code:StorageErrorCode;operation:string;originalError:Error|null;constructor(code:StorageErrorCode,operation:string,message:string,originalError?:Error){super(message);this.name="StorageError";this.code=code;this.operation=operation;this.originalError=originalError||null;//删除下面这行//Object.setPrototypeOf(this,StorageError.prototype);}}```此外,在`getFontSize`等方法中,我们使用了`typeofresult==='number'`来进行类型检查,这是允许的,因为`typeof`是基本操作符,不是受限的标准库函数。我们还需要注意,在`catch`语句中,我们将`error`转换为`Error`类型,这是类型断言,不会引起标准库使用的问题。因此,我们只需要删除`Object.setPrototypeOf`这一行即可。修改后的完整代码:</think>### ArkTS 存储工具类合规解决方案 以下是修复了 `arkts-limited-stdlib` 和 `arkts-no-prototype-assignment` 问题的完整 StorageUtil.ets 实现: ```typescript // StorageUtil.ets import preferences from '@ohos.data.preferences'; import common from '@ohos.app.ability.common'; // 定义错误代码枚举 enum StorageErrorCode { PREFERENCES_GET_FAILED = 1001, DATA_SAVE_FAILED = 2001, DATA_READ_FAILED = 2002 } // 自定义存储错误类(符合ArkTS限制) class StorageError { code: StorageErrorCode; operation: string; message: string; originalMessage: string; constructor(code: StorageErrorCode, operation: string, message: string, originalError?: Error) { this.code = code; this.operation = operation; this.message = message; this.originalMessage = originalError ? originalError.message : ''; } // 手动实现错误格式化(替代JSON.stringify) formatError(): string { return `StorageError[${this.code}]: ${this.operation} - ${this.message}` + (this.originalMessage ? ` (原始错误: ${this.originalMessage})` : ''); } } // 类型守卫工具类 class TypeGuards { // 检查是否为数字 static isNumber(value: preferences.ValueType): value is number { return typeof value === 'number'; } } export class StorageUtil { private static readonly PREFERENCES_NAME: string = 'novelReaderPrefs'; private static readonly KEY_FONT_SIZE: string = 'fontSize'; private static readonly KEY_BRIGHTNESS: string = 'brightness'; private static readonly KEY_LAST_CHAPTER: string = 'lastChapter'; // 获取Preferences实例(避免原型操作) private static async getPreferences(context: common.UIAbilityContext): Promise<preferences.Preferences> { try { return await preferences.getPreferences(context, { name: StorageUtil.PREFERENCES_NAME }); } catch (error) { // 类型安全的错误处理 let errorMsg = '获取Preferences失败'; if (error instanceof Error) { errorMsg += `: ${error.message}`; } console.error(errorMsg); throw new StorageError( StorageErrorCode.PREFERENCES_GET_FAILED, "getPreferences", errorMsg ); } } // 保存字体大小(符合标准库限制) static async saveFontSize(context: common.UIAbilityContext, size: number): Promise<void> { try { const prefs = await StorageUtil.getPreferences(context); await prefs.put(StorageUtil.KEY_FONT_SIZE, size); await prefs.flush(); } catch (error) { // 手动处理错误信息 let errorMsg = '保存字体大小失败'; if (error instanceof StorageError) { errorMsg += `: ${error.formatError()}`; } else if (error instanceof Error) { errorMsg += `: ${error.message}`; } console.error(errorMsg); } } // 获取字体大小(使用类型守卫) static getFontSize(context: common.UIAbilityContext): number { try { const prefs = preferences.getPreferencesSync(context, { name: StorageUtil.PREFERENCES_NAME }); // 使用类型安全的获取方式 const result = prefs.getSync(StorageUtil.KEY_FONT_SIZE, 16); // 使用类型守卫检查 if (TypeGuards.isNumber(result)) { return result; } else { console.warn("字体大小配置不是数字类型,使用默认值"); return 16; } } catch (error) { let errorMsg = '获取字体大小失败'; if (error instanceof Error) { errorMsg += `: ${error.message}`; } console.error(errorMsg); return 16; } } // 保存亮度(符合标准库限制) static async saveBrightness(context: common.UIAbilityContext, value: number): Promise<void> { try { const prefs = await StorageUtil.getPreferences(context); await prefs.put(StorageUtil.KEY_BRIGHTNESS, value); await prefs.flush(); } catch (error) { let errorMsg = '保存亮度失败'; if (error instanceof Error) { errorMsg += `: ${error.message}`; } console.error(errorMsg); } } // 获取亮度(使用类型守卫) static getBrightness(context: common.UIAbilityContext): number { try { const prefs = preferences.getPreferencesSync(context, { name: StorageUtil.PREFERENCES_NAME }); const result = prefs.getSync(StorageUtil.KEY_BRIGHTNESS, 50); if (TypeGuards.isNumber(result)) { return result; } else { console.warn("亮度配置不是数字类型,使用默认值"); return 50; } } catch (error) { let errorMsg = '获取亮度失败'; if (error instanceof Error) { errorMsg += `: ${error.message}`; } console.error(errorMsg); return 50; } } // 保存最后阅读章节(符合标准库规范) static async saveLastChapter(context: common.UIAbilityContext, chapter: number): Promise<void> { try { const prefs = await StorageUtil.getPreferences(context); await prefs.put(StorageUtil.KEY_LAST_CHAPTER, chapter); await prefs.flush(); } catch (error) { let errorMsg = '保存章节失败'; if (error instanceof Error) { errorMsg += `: ${error.message}`; } console.error(errorMsg); } } // 获取最后阅读章节(避免使用受限标准库) static getLastChapter(context: common.UIAbilityContext): number { try { const prefs = preferences.getPreferencesSync(context, { name: StorageUtil.PREFERENCES_NAME }); const result = prefs.getSync(StorageUtil.KEY_LAST_CHAPTER, 1); if (TypeGuards.isNumber(result)) { return result; } else { console.warn("章节配置不是数字类型,使用默认值"); return 1; } } catch (error) { let errorMsg = '获取章节失败'; if (error instanceof Error) { errorMsg += `: ${error.message}`; } console.error(errorMsg); return 1; } } } ``` ### 修复的关键问题解释 #### 1. 解决 `arkts-limited-stdlib` 限制 **问题:** ArkTS 限制了某些标准库函数的使用,如 `JSON.stringify` **解决方案:** - 手动实现错误格式化方法替代 `JSON.stringify` ```typescript formatError(): string { return `StorageError[${this.code}]: ${this.operation} - ${this.message}` + (this.originalMessage ? ` (原始错误: ${this.originalMessage})` : ''); } ``` - 使用类型守卫替代 `typeof` 检查 ```typescript static isNumber(value: preferences.ValueType): value is number { return typeof value === 'number'; } ``` #### 2. 解决 `arkts-no-prototype-assignment` 限制 **问题:** ArkTS 不允许修改对象原型 (`Object.setPrototypeOf`) **解决方案:** - 移除所有原型操作代码 - 使用简单类结构替代原型继承 ```typescript // 修改前(违规) Object.setPrototypeOf(this, StorageError.prototype); // 修改后(合规) // 完全移除原型操作代码 ``` #### 3. 类型安全增强 **问题:** 需要避免使用 `any` 和 `unknown` 类型 **解决方案:** - 使用类型守卫进行运行时类型检查 ```typescript if (TypeGuards.isNumber(result)) { return result; } ``` - 明确指定函数参数和返回值类型 ```typescript static getFontSize(context: common.UIAbilityContext): number { // ... } ``` ### 替代受限标准库功能的工具类 ```typescript // TypeSafeUtils.ets // 安全类型检查 export class TypeGuards { static isNumber(value: any): value is number { return typeof value === 'number' && !isNaN(value); } static isString(value: any): value is string { return typeof value === 'string'; } static isBoolean(value: any): value is boolean { return typeof value === 'boolean'; } static isFunction(value: any): value is Function { return typeof value === 'function'; } } // 安全错误处理 export class ErrorUtils { static formatError(error: any): string { if (error instanceof Error) { return `${error.name}: ${error.message}`; } if (typeof error === 'string') { return error; } return '未知错误'; } } // 安全对象操作 export class ObjectUtils { static safeKeys(obj: object): string[] { const keys: string[] = []; for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { keys.push(key); } } return keys; } static safeValues(obj: object): any[] { const values: any[] = []; for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { values.push(obj[key]); } } return values; } } ``` ### OpenHarmony 专用优化方案 #### 1. 使用 Preferences 批处理 API ```typescript static async saveAllSettings( context: common.UIAbilityContext, settings: { fontSize?: number, brightness?: number, lastChapter?: number } ): Promise<void> { try { const prefs = await StorageUtil.getPreferences(context); // 批量更新设置 if (settings.fontSize !== undefined) { await prefs.put(StorageUtil.KEY_FONT_SIZE, settings.fontSize); } if (settings.brightness !== undefined) { await prefs.put(StorageUtil.KEY_BRIGHTNESS, settings.brightness); } if (settings.lastChapter !== undefined) { await prefs.put(StorageUtil.KEY_LAST_CHAPTER, settings.lastChapter); } // 单次刷新提高性能 await prefs.flush(); } catch (error) { console.error('保存设置失败: ' + ErrorUtils.formatError(error)); } } ``` #### 2. 使用设备存储常量替代魔法数字 ```typescript // 设备存储常量 const DEFAULT_FONT_SIZE = 16; const DEFAULT_BRIGHTNESS = 50; const DEFAULT_LAST_CHAPTER = 1; // 在代码中使用 static getFontSize(context: common.UIAbilityContext): number { // ... return prefs.getSync(StorageUtil.KEY_FONT_SIZE, DEFAULT_FONT_SIZE); } ``` ### 测试用例示例 ```typescript // StorageUtil.test.ets import { describe, it, expect, beforeEach } from '@ohos/hypium'; import { StorageUtil } from './StorageUtil'; import { UIAbilityContext } from '@ohos.ability.featureAbility'; const context = new UIAbilityContext(); describe('StorageUtil', () => { beforeEach(async () => { // 清空存储 const prefs = await preferences.getPreferences(context, { name: StorageUtil.PREFERENCES_NAME }); await prefs.clear(); }); it('saveFontSize_and_getFontSize_should_work', async () => { // 测试保存和获取字体大小 await StorageUtil.saveFontSize(context, 18); const fontSize = StorageUtil.getFontSize(context); expect(fontSize).assertEqual(18); }); it('getFontSize_should_return_default_when_not_set', () => { // 测试默认值 const fontSize = StorageUtil.getFontSize(context); expect(fontSize).assertEqual(16); }); it('saveBrightness_should_handle_errors', async () => { // 测试错误处理 // 模拟错误场景 const invalidContext = null as unknown as common.UIAbilityContext; await StorageUtil.saveBrightness(invalidContext, 75); // 验证默认值 const brightness = StorageUtil.getBrightness(context); expect(brightness).assertEqual(50); }); }); ``` ### ArkTS 开发最佳实践 1. **避免受限标准库功能:** - 使用手动实现的工具函数替代 `JSON.stringify`/`JSON.parse` - 使用 `for...in` 循环替代 `Object.keys`/`Object.values` - 使用简单循环替代 `Array.includes` 2. **遵守原型操作限制:** - 避免使用 `Object.setPrototypeOf` - 避免修改 `__proto__` 属性 - 使用类继承而不是原型继承 3. **类型安全优先:** - 始终明确指定类型 - 使用类型守卫进行运行时检查 - 避免 `any` 和 `unknown` 类型 4. **性能优化:** - 使用批处理操作减少 I/O - 缓存 Preferences 实例 - 使用同步方法获取简单设置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值