目录

1.抽象类

2.装饰器

3.命名空间

4.模块

5.编译配置文件

6.python的类型注解

1.抽象类

抽象类(abstract class)做为其它派生类的基类使用。 它们一般不会直接被实例化。 不同于接口,抽象类可以包含成员的实现细节。 abstract关键字是用于定义抽象类和在抽象类内部定义抽象方法。

代码如下所示:

// 抽象父类
abstract class Animal{
abstract makeSound(): void; // 抽象方法,没有函数体
constructor(public name: string){ // 抽象类的构造方法 }
desc(): void { // 抽象类中也可以定义子类的公共方法或公共属性
console.log('roaming the earch...');
}
} // 抽象子类
abstract class Dog extends Animal{
abstract move(): string;
} // 具象类/具体类
class ChineseGardenDog extends Dog{
public name:string;
makeSound(){
return "汪汪汪~"
}
move(): string {
return "奔跑中...."
}
constructor(name: string){
super(name); // 继承了抽象类的子类,必须对父类进行初始化
}
} var dog = new ChineseGardenDog("来福");
console.log(dog.name);
console.log(dog.makeSound());

2.装饰器

随着TypeScript和ES6里引入了类,在一些场景下我们需要额外的特性来支持标注或修改类及其成员。 装饰器(Decorators)为我们在类的声明及成员上通过元编程语法添加标注提供了一种方式。装饰器是一种特殊类型的声明,它能够被附加到类声明方法访问符属性参数上。

代码如下所示:

function derator1() {
console.log("derator1(): evaluated");
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("derator1(): called");
}
} function derator2(name:string) {
console.log(`derator2(): evaluated,name=${name}`);
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
console.log(`derator2(): called,name=${name}`);
}
} class Demo {
@derator1()
@derator2("xiaoming")
show() {
console.log("show()执行了")
}
} var d = new Demo();
d.show(); /*
* 输出结果顺序:
* derator1(): evaluated
* derator2(): evaluated,name=xiaoming
* derator2(): called,name=xiaoming
* derator1(): called
* show()执行了
*
*/

3.命名空间

当项目大了以后,需要创建和声明的函数,类就多了,自然人也就多了,人多就坏事。想想全国有几个张三?

命名空间(namespace)一个最明确的目的就是解决重名问题。

命名空间定义了标识符的可见范围,一个标识符可在多个名字空间中定义,它在不同名字空间中的含义是互不相干的。这样,在一个新的名字空间中可定义任何标识符,它们不会与任何已有的标识符发生冲突,因为已有的定义都处于其他名字空间中。

1.定义一个命名空间

// 命名空间的名称采用驼峰式写法
namespace App{
// 需要在命名空间外部可以调用 当前命名空间的类,函数和接口等,则需要在左边添加 export 关键字。
// 变量
export var username:string="App空间的变量";
// 常量,一旦定义以后,不能修改值
export const NAME = "App命名空间的常量";
// 函数
export function func(){
return "App命名空间里面的func"
}
// 类
export class Humen{ }
// 当然,在当前命名空间下也是可以执行代码的
}

2.导入命名空间

main.ts,代码:

导入其他命名空间的格式:/// <reference path = "文件名" />,可以导入多个命名空间,一行一个。

/// <reference path="app.ts" />
console.log(App.func()); // 调用其他命名空间的内容,必须以"命名空间的名称.xxxx"格式进行调用
console.log(App.NAME);
console.log(App.username);
console.log(new App.Humen());

使用了命名空间以后,编译命令需要稍微调整如下:

tsc --out main.js main.ts  # 必须指定--out参数才能正常编译

4.模块

TypeScript 模块的设计理念是可以更换的组织代码。模块是在其自身的作用域里执行,并不是在全局作用域,这意味着定义在模块里面的变量、函数和类等在模块外部是不可见的。

typescript提供了两种模块:内部模块外部模块,因为外部模块需要依赖第三方框架才可以使用,例如:commonjs,requirejs等。所以在此,我们只简单介绍内部模块的声明和使用。

1.内部模块

1.声明模块

app.ts,代码

module App{
export class Humen {
desc(){
console.log("hello");
}
} export function func(){
console.log("hello, func");
} }

2.调用模块

main.ts,代码

/// <reference path="./app.ts">
var people = new App.Humen();
people.desc();
App.func();

使用了内部模块以后,编译命令和命名空间一样:

tsc --out main.js main.ts

2.外部模块

out.js,代码

class Humen{
uname:string;
constructor(uname){
this.uname = uname;
}
desc() {
return `您好,我叫 ${this.uname}`;
}
}
export { Humen };
export { Humen as People };

导入模块,main.ts,代码:

import { Humen, People } from "./Out";
let obj1 = new Humen("小白");
let obj2 = new People("小黑");
obj1.desc();
obj2.desc();

编译命令:

tsc --module es6 main.ts   # --module 表示代码中编写模块的规范和标准

5.编译配置文件

基于typescript开发的项目根目录,一般都会存在一个文件,叫tsconfig。这是typescript的编译配置文件。

配置选项:https://www.tslang.cn/docs/handbook/compiler-options.html

tsconfig.json,常用配置项说明,代码:

// 当前配置文件名必须固定是: tsconfig.json
// 同时,json文件中不能出现注释的,所以此处的注释仅仅是为了学习,开发中决不能有
{
"compilerOptions": {
"module": "system", // 项目中编写模块的规范标准
"noImplicitAny": true, // 表达式或声明上有隐含的 any类型时报错
"removeComments": true, // 删除所有注释,除了以 /!*开头的版权信息。
"preserveConstEnums": true, // 保留const和Enums声明
"outDir": "script", // 编译结果保存目录
// "outFile": "../../built/local/tsc.js", // 编译以后输出的文件,一般用不上
"sourceMap": true, // 生成相应的 .map文件
"experimentalDecorators": true, // 启用实验性的ES装饰器
"lib": [ // 编译过程中需要引入的库文件的列表
"es5",
"dom",
"es2015.promise"
]
},
"files": [ // 指定要编译的文件列表, 与include和exclude冲突,开发中,一般使用exclude
"main.ts"
]
// "include": [ // 指定要编译的文件所在目录
//// "src/**/*",
// "./"
// ],
// "exclude": [ // 指定在编译时排除的文件目录
// "node_modules",
// "**/*.spec.ts"
// ]
}

6.python的类型注解

1.typing模块

自python3.5开始,PEP484为python引入了类型注解(type hints)

  • 类型检查,防止运行时出现参数和返回值类型、变量类型不符合。

  • 作为开发文档附加说明,方便使用者调用时传入和返回参数类型。

  • 该模块加入后并不会影响程序的运行,不会报正式的错误,只有提醒。

    pycharm目前支持typing检查,参数类型错误会黄色提示。

2.常用类型

  • int,long,float: 整型,长整形,浮点型

  • bool,str: 布尔型,字符串类型

  • List, Tuple, Dict, Set:列表,元组,字典, 集合

  • Iterable,Iterator:可迭代类型,迭代器类型

  • Generator:生成器类型

3.基本类型指定

from typing import List,Dict,Tuple,Union
# 整型
num:int = 100
# 字符串
data:str = "200"
# 布尔值
bo:bool = True
# 列表
data_list:List[str] = ["1","2","3"]
# 字典
data_dict:Dict[str, str] = {"name":"xiaoming",}
# 元组[限制数据和类型]
data_tuple:Tuple[int,int,bool] = (1,2,False) # 联合类型[泛型]
U1 = Union[str,int] # 只能是字符串或者整形
data_union1:U1 = "20"
data_union2:U1 = 200
data_union3:U1 = [1,2,3] # 此处不符合要求,出现黄色提示 def test(a:int, b:str) -> str:
print(a, b)
return 1000 if __name__ == '__main__':
test('test', 'abc') """
函数test,
a:int 指定了输入参数a为int类型,
b:str b为str类型,
-> str 返回值为str类型。 可以看到,
在方法中,我们最终返回了一个int,此时pycharm就会有警告;
当我们在调用这个方法时,参数a我们输入的是字符串,此时也会有警告;
但非常重要的一点是,pycharm只是提出了警告,但实际上运行是不会报错,毕竟python的本质还是动态语言
"""

4.复杂的类型标注

from typing import List
Vector = List[float] def scale(scalar: float, vector: Vector) -> Vector:
return [scalar * num for num in vector] # 类型判定: 传递进行的数据只要类似Vector格式即可,这里也是鸭子类型所导致的.
new_vector = scale(2.0, [1.0, -4.2, 5.4])
from typing import Dict, Tuple, Sequence

ConnectionOptions = Dict[str, str]
Address = Tuple[str, int]
Server = Tuple[Address, ConnectionOptions] def broadcast_message(message: str, servers: Sequence[Server]) -> None:
... # The static type checker will treat the previous type signature as
# being exactly equivalent to this one.
def broadcast_message(
message: str,
servers: Sequence[Tuple[Tuple[str, int], Dict[str, str]]]) -> None:
...
):
...
"""
这里需要注意,元组这个类型是比较特殊的,因为它是不可变的。
所以,当我们指定Tuple[str, str]时,就只能传入长度为2,
并且元组中的所有元素都是str类型
"""

5.泛型指定

from typing import Sequence, TypeVar

T = TypeVar('T')      # 定义泛型变量,可以是任意类型的数据
b2:T = True # b2的值可以是任意类型数据 def first(l: Sequence[T]) -> T: # Generic function
return l[0] A = TypeVar('A', bool, str, bytes) # 定义当前泛型的范围只能是字符串或者bytes类型
b3:A = "hello"
b4:A = "hello".encode()
b5:A = True

6.创建变量时的类型指定

from typing import NamedTuple

class Employee(NamedTuple):
name: str
id: int = 3 employee = Employee('Guido')
assert employee.id == 3

7.不足之处:提示错误而不影响执行

from typing import List

def test(b: List[int]) -> str:
print(b)
return 'test' if __name__ == '__main__':
test([1, 'a']) """
从这个例子可以看出来,虽然我们指定了List[int]即由int组成的列表,
但是,实际中,只要这个列表中存在int(其他的可以为任何类型),就不会出现警告
"""

day134:2RenMJ:TypeScript的抽象类&装饰器&命名空间&模块&编译配置文件&python中的类型注解的更多相关文章

  1. python中闭包和装饰器的理解(关于python中闭包和装饰器解释最好的文章)

    转载:http://python.jobbole.com/81683/ 呵呵!作为一名教python的老师,我发现学生们基本上一开始很难搞定python的装饰器,也许因为装饰器确实很难懂.搞定装饰器需 ...

  2. python学习笔记(5)--迭代器,生成器,装饰器,常用模块,序列化

    生成器 在Python中,一边循环一边计算的机制,称为生成器:generator. 如: >>> g = (x * x for xin range(10)) >>> ...

  3. Python_oldboy_自动化运维之路_函数,装饰器,模块,包(六)

    本节内容 上节内容回顾(函数) 装饰器 模块 包 1.上节内容回顾(函数) 函数 1.为什么要用函数? 使用函数之模块化程序设计,定义一个函数就相当于定义了一个工具,需要用的话直接拿过来调用.不使用模 ...

  4. python3.5-day5_迭代器_生成器_装饰器_模块

    笔者QQ 360212316 迭代器&生成器 生成器: 一个函数调用返回一个迭代器,那这个函数叫做生成器,如果函数中包含yield语法,那么这个函数就会变成生成器 生成器的特点: 1.生成器必 ...

  5. 理解Python中的装饰器//这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档

    转自:http://www.cnblogs.com/rollenholt/archive/2012/05/02/2479833.html 这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档 ...

  6. python学习day14 装饰器(二)&模块

    装饰器(二)&模块 #普通装饰器基本格式 def wrapper(func): def inner(): pass return func() return inner def func(): ...

  7. Python全栈工程师(装饰器、模块)

    ParisGabriel                每天坚持手写  一天一篇  决定坚持几年 全栈工程师     Python人工智能从入门到精通 装饰器 decorators(专业提高篇) 装饰 ...

  8. python基础编程: 函数示例、装饰器、模块、内置函数

    目录: 函数示例 装饰器 模块 内置函数 一.函数示例: 1.为什么使用函数之模块化程序设计: 不使用模块程序设计的缺点: 1.体系结构不清晰,可主读性差: 2.可扩展性差: 3.程序冗长: 2.定义 ...

  9. Python基础(闭包函数、装饰器、模块和包)

    闭包函数 格式: def 函数名1(): def 函数名2(): 变量 = 值 return 变量 return 函数名2 func = 函数名1() key = func()

  10. @classmethod, @staticmethod和@property这三个装饰器的使用对象是在类中定义的函数。下面的例子展示了它们的用法和行为:

    class MyClass(object): def __init__(self): self._some_property = "properties are nice" sel ...

随机推荐

  1. 怎样修改linux内核

    1.先查看linux内核 uname -a 2.打开内核配置文件 sudo vi /etc/default/grub 3.跟新grub文件 sudo update-grub 4.最后重启电脑 sudo ...

  2. 如何配置php.ini才能让PHP性能最大优化

    用于生产环境中的PHP需要对其进行优化,可以让PHP自身发挥更好的性能,除了写好PHP代码,还要配置好php.ini.本文从内存.文件上传.会话缓冲输出.真实路径缓存这几个方面讲解php.ini的配置 ...

  3. OO_Lab2总结博客

    OO_Lab2 一.单元内容 本单元内容为规格化设计,即通过参考已经完成的JML描述实现一个社交网络相关功能. 本单元整体来说难度不大,但是却是我最惨的一次作业,所以本博客可能会主要谈一谈测试中的一些 ...

  4. 实验2 C语言分支语句、循环语句应用编程

    一.实验目的 掌握格式化输出函数printf()和格式化输入函数scanf()的用法 掌握单个字符输出函数putchar()和单个字符输入函数getchar()的用法 理解结构化程序设计的三种基本结构 ...

  5. 第二节 printf语句和C++中的判断结构

    第二节 printf语句和C++中的判断结构 1.1printf语句作用 保留几位小数:%.4lf 保留四位小数 %.3lf 保留三位小数, 格式化输出:整数:printf("%5d!&qu ...

  6. This class is not trusted to be serialized as ObjectMessage payload.ActiveMQ序列化设置

    引子 ObjectMessage引入的生产者和消费者之间的类路径耦合,ActiveMQ支持他们作为JMS规范的一部分. ObjectMessage对象依赖marshal/unmarshal进行java ...

  7. json提取器通过多条件筛选提取ID

    可能在某些列表中如名称会有重复,此时就需要使用多个搜索条件来判定唯一性 $.data.[?(@.tymc=="测试测试")].[?(@.plat_merchandise_id==& ...

  8. 一分钟教你分清各种光纤跳线接头(SC、ST、FC、LC、MPO)

    一分钟教你分清各种光纤跳线接头(SC.ST.FC.LC.MPO)  市场上常见的光纤跳线有以下几种接头:SC.ST.FC.LC.MPO,相信很多入门者和小编一样,面对各种英文缩写也是我只认识他们,却不 ...

  9. Qt 5.15.2 QTextEdit无法设置新字体的处理方式

    首发于我的个人博客:xie-kang.com 博客内有更多文章,欢迎大家访问 原文地址 在使用QT 5.15.2 开发的过程中碰到了件怪事,下列代码无法给QTextEdit选中的文字设置字体: QTe ...

  10. mysql 存储国过程实现竖表变横表(将行数据值变为字段)

    示例: 表结构如下: CREATE TABLE `pressure` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键', `presurena ...