首页 文章 精选 留言 我的

精选列表

搜索[知识资产沉淀],共10000篇文章
优秀的个人博客,低调大师

Python高级知识点学习(六)

围棋少年 Python中的迭代协议 迭代协议有两个概念: 可迭代类型(Iterable) 迭代器(Iterator) 迭代器:迭代器是访问集合内元素的一种方式, 一般用来遍历数据。 迭代器和以下标的访问方式不一样, 迭代器是不能返回的, 迭代器提供了一种惰性方式数据的方式。 可迭代对象(Iterable) 和 迭代器(Iterator) 是不同的。 可迭代对象: 实现__iter__这个魔法函数 迭代器: 实现__next__这个魔法函数 实现__iter__这个魔法函数 from collections.abc import Iterable, Iterator a = [1, 2] print(isinstance(a, Iterable)) print(isinstance(a, Iterator)) 打印结果: True False 上边代码,因为a是一个list,而list是一个可迭代对象并不是迭代器,因为list对象中没有__next__方法。 生成器 生成器函数:函数里只要有yield关键字,它就是生成器对象。 生成器对象在python编译字节码的时候就产生了。 生成器对象也是实现了迭代器协议的,所以可以使用for循环遍历到它的值。 def gen_func(): yield 1 gen = gen_func() for value in gen: print(value) 打印结果: 1 Python 中的GIL GIL:global interpreter lock (cpython) GIL:全局解释器锁。 python中一个线程对应于c语言中的一个线程。 GIL使得同一个时刻只有一个线程在一个cpu上执行字节码, 也就意味着无法将多个线程映射到多个cpu上执行。 GIL锁分配给某一线程后,并不是说这个线程执行完了之后它才会释放把它交给另外一个线程,它不是整个过程完全占有,它实际上是会在适当的时刻释放的,是结合了字节码执行的行数比如他执行了1000行字节码之后,它会释放,然后另外一个线程就可以得到运行。 GIL释放: 会根据执行的字节码行数以及时间片释放gil。 gil在遇到io的操作时候主动释放。 total = 0 def add(): global total for i in range(1000000): total += 1 def desc(): global total for i in range(1000000): total -= 1 thread1 = threading.Thread(target=add) thread2 = threading.Thread(target=desc) thread1.start() thread2.start() thread1.join() thread2.join() print(total) 上边代码两个线程分别执行两个函数,两个函数对同一变量做加减操作,本来应该先加到1000000再减1000000最终打印出0,但事实上是不会打印0的。 多线程编程 IO密集型时,适合多线程。 CPU密集型时,适合多进程。 多线程编程是我们几乎所有编程语言中都会遇到的问题。 操作系统能够切换和调度的最小单元是线程。 在最开始的时候,操作系统能够调度的最小单元是进程,但是由于进程对系统资源消耗非常大,所以后期就演变出了线程。 第一种方式:通过Thread类实例化 def get_detail_html(url): print("get detail html started") time.sleep(2) print("get detail html end") def get_detail_url(url): print("get detail url started") time.sleep(4) print("get detail url end") if __name__ == "__main__": thread1 = threading.Thread(target=get_detail_html, args=("",)) thread2 = threading.Thread(target=get_detail_url, args=("",)) # 设置为守护线程,随着主线程退出,子线程也退出 #thread1.setDaemon(True) #thread2.setDaemon(True) start_time = time.time() thread1.start() thread2.start() # 等待线程1,2执行完成 再执行完主线程; thread1.join() thread2.join() print(time.time() - start_time) 上边代码中,两个线程分别执行两个函数,主线程下有两个子线程。 thread1.setDaemon(True)这个操作是把thread1设置为守护线程,随着主线程退出,thread1也退出。thread1.join()这个操作是把主线程等待thread1执行完再执行完主线程。 第二种方式:通过重载Thread来实现多线程 def get_detail_html(url): print("get detail html started") time.sleep(2) print("get detail html end") def get_detail_url(url): print("get detail url started") time.sleep(4) print("get detail url end") class GetDetailHtml(threading.Thread): def __init__(self, name): super().__init__(name=name) def run(self): print("get detail html started") time.sleep(2) print("get detail html end") class GetDetailUrl(threading.Thread): def __init__(self, name): super().__init__(name=name) def run(self): print("get detail url started") time.sleep(4) print("get detail url end") if __name__ == "__main__": thread1 = GetDetailHtml("get_detail_html") thread2 = GetDetailUrl("get_detail_url") start_time = time.time() thread1.start() thread2.start() thread1.join() thread2.join() print("last time: {}".format(time.time()-start_time)) 上边代码继承threading.Thread必须重载run方法。 线程同步Lock、RLock 为什么要线程同步? 现有两个函数,分别是对全局变脸a进行加减操作,两个函数使用两个线程来运行,一个线程负责把a加一,另一个负责把a减一,上代码: a = 0 def add(a): a += 1 def desc(a): a-=1 首先使用内置方法dis()看一下两个函数字节码是什么样子的: import dis def add(a): a += 1 def desc(a): a-=1 print(dis.dis(add)) print(dis.dis(desc)) 打印结果: 63 0 LOAD_FAST 0 (a) 2 LOAD_CONST 1 (1) 4 INPLACE_ADD 6 STORE_FAST 0 (a) 8 LOAD_CONST 0 (None) 10 RETURN_VALUE None 66 0 LOAD_FAST 0 (a) 2 LOAD_CONST 1 (1) 4 INPLACE_SUBTRACT 6 STORE_FAST 0 (a) 8 LOAD_CONST 0 (None) 10 RETURN_VALUE None 上边代码打印结果: 看下add的里边字节码: LOAD_FAST:首先把 a LOAD 到内存中 LOAD_CONST :再把1 LOAD 到内存中 INPLACE_ADD:执行加的操作 STORE_FAST:将加完的值赋值给 a desc里边也是一样的,分四步,不同的是desc里执行的是减法。 如果同时执行add字节码和desc字节码时,之前笔记中提过,执行以上四个步骤时随时都可能释放gil锁,因为字节码的数量已经满了,以上四步任何一步骤都可能释放gil锁切换到另外一个线程,所以有可能造成一个结果,就是a要么等于1,要么等于-1,但是我们期望的是a 等于0,这时候就需要线程同步来解决问题。 我们希望在执行add函数的代码段时,另一个线程中的desc代码段是停止的,这就是线程同步机制。 python给我们提供了一个机制,叫做锁:from threading import Lock 在运行一个代码段时,加一把锁,等运行完了,再释放锁。 from threading import Lock total = 0 # 声明一把锁 lock = RLock() def add(): global lock global total for i in range(1000000): # 获得锁 lock.acquire() total += 1 # 释放锁 lock.release() def desc(): global total global lock for i in range(1000000): lock.acquire() total -= 1 lock.release() import threading thread1 = threading.Thread(target=add) thread2 = threading.Thread(target=desc) thread1.start() thread2.start() thread1.join() thread2.join() print(total) 打印结果: 0 上边代码不管累加多少次最终结果都是0。 如果没有释放锁,会导致死锁。 使用锁会影响性能。 RLock: 在同一个线程里面,可以连续调用多次acquire, 一定要注意acquire的次数要和release的次数相等。 在同一个线程中,可以使用RLock。

优秀的个人博客,低调大师

Python高级知识点学习(五)

dict的子类 首先,不建议自己编写代码继承dict和list这种原生使用c语言编写的,因为有时候,用c语言写的dict不会调用python写的覆盖的方法。 如果确实有继承dict来写代码的需求,可以使用UserDict,继承这个UserDict。 UserDict这个内部使用了python语言实现了c语言写的逻辑。 from collections import UserDict class Mydict(UserDict): def __setitem__(self, key, value): super().__setitem__(key, value*2) my_dict = Mydict(one=1) print (my_dict) 打印结果: {'one': 2} set和fronzenset set集合: 无序 不重复 set 接受一个可迭代对象 frozenset集合: 一旦设置好就无法修改。 frozenset为不可变类型。 相对于可变类型来说的好处,可以作为dict的key。 set的初始化方法: set([a, b, c]) a = {a, b, c} 两种都可以初始化 dict、set实现原理 当我们了解了背后的实现原理,就可以判断什么情况下使用dict以及为什么要使用dict。 dict查找的性能远远大于list。 在list中随着list数据的增大 查找时间会增大。 在dict中查找元素不会随着dict的增大而增大。 dict原理实际上就是利用hash算法。 数组和链表相比来说最大的优势,就是它可以做到任何一个位置直接存取而不需要从头到尾遍历,因为数组是一段连续的空间,数组取数据的时间复杂度是O(1)。 dict的key或者set的值,都必须是可以hash的。不可变对象都是可hash的, str, fronzenset, tuple。 自己实现的类重载__hash__这个魔法函数,让它可以变为可哈希对象。 dict的内存花销大,但是查询速度快, 自定义的对象或者python内部的对象都是用dict包装的。 dict的存储顺序和元素添加顺序有关,添加数据有可能改变已有数据的顺序。 Python中的变量是什么 python和java中的变量本质不一样,python的变量实质上是一个指针。我们可以理解变量就是一个便利贴, 例如:a = 1 先成对象,然后贴便利贴,把a贴在1上面。 a = [1, 2, 3] b = a print(id(a), id(b)) 打印结果: a和b的地址值一样。 is 和 == 的区别 is是判断对象的id是否相同,但是注意看下边例子: a = [1, 2, 3, 4] b = [1, 2, 3, 4] print (id(a), id(b)) print (a is b) 输出结果: 4446597320 4446597640 False 上边这种用法得到的结果很正常,再看下边代码: a = 1 b = 1 print (id(a), id(b)) print (a is b) 运行结果: 4325627840 4325627840 True 这种情况下,a和b指向的是同一个。这是由于Python内部机制决定的,将小正数建立一个全局唯一的对象,小段字符串也是一样的。 a = [1, 2, 3] b = [1, 2, 3] print(a==b) 返回True 因为: list里边实现了一个魔法函数 __eq__,当我们调用a==b这种模式的时候,会调用__eq__这个魔法函数,从而来判断值是否相等。 它们的值是相等的,只是不是同一个对象而已,所有a==b是True。 垃圾回收和del语句 cpython中垃圾回收的算法是采用 引用计数 a = 1 b = a 此时,1这个对象上就又有一个计数器,a = 1 时会在计数器上加1,b如果指向的还是1,1上边的计数器会再加1,当不使用时,执行del a,他就会将引用计数器减1,当引用计数器减到0时,python解释器会将对象回收。 对象只有在计数器减到0时,才会被回收,del只是减计数器的功能。 a = object() b = a del a print(b) print(a) 打印结果: <object object at 0x104a86100> NameError: name 'a' is not defined 可以看到,执行del后,只是把a销毁了,b还在。 __del__魔法函数: 可以在__del__魔法函数中实现自己的逻辑,当python解释器回收对象的时候,会调用对象的__del__魔法函数,它可以帮我们在回收对象时做一些事。 @property的用法 我们在读源码时,往往会看到这这种方法: @property def hello(self): pass @property 这个装饰器会把函数变为属性描述符,怎么说? 看代码: class Allen(object): def word(self): return 'word' @property def hello(self): return 'hello' a = Allen() print(a.hello) print(a.word()) 运行结果: hello word 可以发现,@property这个装饰器把取方法的模式变为取属性。 魔法函数__getattr__、__getattribute__介绍 魔法函数是python解释器内部需要用的方法,它是整个python动态特性的最根本原因。 __getattr__:就是在查找不到属性的时候调用。 例1: class User: def __init__(self, info): self.info = info def __getattr__(self, item): return '2' if __name__ == "__main__": user = User('allen') print(user.info) print(user.age) 运行结果: allen 2 例2: class User: def __init__(self, info={}): self.info = info def __getattr__(self, item): return self.info[item] if __name__ == "__main__": user = User(info={"name": "allen", "age": "3"}) print(user.name) 打印结果: allen __getattribute__ : 比__getattr__更高级,只要查找属性,就会首先进入__getattribute__这个魔法函数,强制进入,无条件的。 __getattribute__这个魔法函数尽量不要去重写,因为如果一旦写不好,整个类的属性访问就会崩溃掉,一般写框架时会用到这个魔法函数。 class User: def __init__(self,info={}): self.info = info def __getattr__(self, item): return self.info[item] def __getattribute__(self, item): return "10" if __name__ == "__main__": user = User(info={"name":"allen"}) print(user.name) print(user.test) 打印结果: 10 10 属性描述符和属性查找过程 一个类只需要实现__get__、__set__、__delete__这三个中的任意一个方法,它就算是属性描述符。 通过属性描述符,可以控制在赋值的时候它的行为,在属性设置的时候参数检查。 属性描述符有两种: 数据属性描述符:实现__get__ 和 __set__就是数据属性描述符。 非数据属性描述符:只实现一个__get__方法就是非数据属性描述符。 数据属性描述符 和 非数据属性描述符 它们的属性查找过程是不一样的。 前边提到的属性查找过程,先查找实例中的属性,然后查找类中的属性,实际上它有更加详细的查找过程。 魔法函数__new__ 和 __init__ 区别 __new__ 魔法函数在python新式类才会有 python2.2之前没有这个。 class User: def __new__(cls, *args, **kwargs): print(" in new ") return super().__new__(cls) def __init__(self): print(" in init") pass if __name__ == "__main__": user = User() 打印结果: in new in init __new__魔法函数允许在生成对象之前加逻辑,自定义对象生成过程,传递进来的是类。 __init__方法传递进去的是对象。 __new__ 在 __init__ 之前调用。 __new__中必须return super().__new__(cls)才会调用__init__方法。 def __new__(cls, *args, **kwargs):这个中的*args,和**kwargs,代表的是传入的参数。

优秀的个人博客,低调大师

Python高级知识点学习(三)

mro算法 类属性和实例属性的查找顺序 何为类属性:定义在类内部的的一些变量或者方法,都统称为类属性 何为实例属性:定义在对象内部的的一些变量或者方法,都统称为实例属性 对象也就是实例的意思。 class A: aa = 1 def __init__(self, x, y): self.x = x self.y = y a = A(2, 3) 类也是对象,看上边代码,实际上有两个空间,A 和 a 两个不同的空间。单继承时,属性查找方式,向上查找,首先查找对象里,再查找类中 在多继承时,会很复杂 python2.2之前,python里的类叫经典类,经典类继承方式如果不显式继承object,实际上是不会自动继承object,Python3中,经典类已经不存在了,都叫做新式类。经典类中,深度优先查找 。 Python2.3之后,广度优先也没有了,至今都采用C3算法Python3多重继承C3算法: #新式类 class D: pass class E: pass class C(E): pass class B(D): pass class A(B, C): pass print(A.__mro__) 打印结果:(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.C'>, <class '__main__.E'>, <class 'object'>)可以看到继承顺序是 A - B - D - C - E - object 类方法静态方法和实例方法 实例方法:实例方法很常见,通常我们在类里定义的都是实例方法, 只是针对于实例进行操作,实例方法中第一个参数:self,self代表的就是实例本身 静待方法: 带@staticmethod装饰器的方法叫静态方法,静态方法不需要接受cls或self,和普通的函数用法一样 类方法: 带@classmethod装饰器的方法叫做类方法,类方法第一个参数是cls,代表的是类本身,(这里的cls可以修改为任意形式的代表) def a(self): pass @staticmethod def b(): pass @classmethod def c(cls): pass Python中的私有属性 双下划綫开头表示私有属性,私有属性的访问,只能在类中的公共方法中访问,类外部防问不到,无法通过实例访问。 私有属性不仅仅是变量 还可以是函数。 class User: def __init__(self, birthday): self.__birthday = birthday user = User(2000) print(user.birthday) 运行结果: AttributeError: 'User' object has no attribute 'birthday' 以上代码块结果就是访问不到私有属性。 但是,私有不是绝对的,只是加了一个小技巧,Python中将私有属性的访问变形成这种: class User: def __init__(self, birthday): self.__birthday = birthday user = User(2000) print(user._User__birthday) 运行结果: 2000 可以看到,通过变量_User__birthday这个就可以访问到私有属性。 Java中的反射机制也是无法做到绝对安全的,从语言层面讲,没有绝对的私有属性,Python简单一些 Java麻烦一些。 Python自省 Python对象自省何为自省?自省是通过一定的机制查询到对象的内部结构使用__dict__魔法函数,dict是用C语言写的 性能高,做了很多优化,推荐使用。 也可以使用dir() ,dir()会列出类中所有属性,推荐使用。 class Student(): def __init__(self, scool_name): self.scool_name = scool_name if __name__ == "__main__": user = Student("zhao") #通过__dict__查询属性 print(user.__dict__) 打印结果: {'scool_name': 'zhao'} class Student(): def __init__(self, name): self.name = name if __name__ == "__main__": user = Student("zhao") user.__dict__["school_addr"] = "北京市" print(user.school_addr) print(user.name) a = [1, 2] print(dir(a)) print(dir(user)) 打印结果: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'school_addr', 'scool_name'] ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] Python中super()函数 super()就是调用父类。 class A: def __init__(self): print('is A') class B(A): def __init__(self): print('is B') # 在某些情况下,我们希望在运行完以上代码调用父类的init方法,一般在Python3中使用下面这种方法调用 super().__init__() if __name__ == "__main__": b = B() 打印结果: is B is A super()就是调用父类,其实这样讲并不准确,super()函数调用其实是按照mro查找的顺序调用的。 class A: def __init__(self): print("A") class B(A): def __init__(self): print("B") super().__init__() class C(A): def __init__(self): print("C") super().__init__() class D(B, C): def __init__(self): print("D") super().__init__() if __name__ == "__main__": print(D.__mro__) d = D() 打印结果: (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>) D B C A 既然我们重写子类的构造函数, 为什么还要去调用super再次调用父类构造函数?有些时候,为了使用父类中的一些已经写好的方法,所以会有使用super的情况。 上下文管理器 首先介绍下这种用法: try: print("code started") raise KeyError return 1 except KeyError as e: print ("key error") return 2 else: print("other error") return 3 finally: print ("finally") return 4 result = exe_try() print (result) 运行结果: code started key error finally 4 在finally语句块中的代码,不管上边代码是否发生异常都会执行finally中的代码,优先finally中的return,其次return上边的。 上下文管理器,也就是with语句,实质上就是为了解放try finally这种写法而诞生的。 上下文管理器是如何完成的呢?python是基于协议进行编程的,上下文管理器就是一种协议:上下文管理器协议。 上下文管理器协议可以使用是因为实现了两个魔法函数:__enter__和__exit__ class Sample: def __enter__(self): print("enter") # 获取资源 return self def __exit__(self, exc_type, exc_val, exc_tb): # 释放资源 print("exit") def do_something(self): print("doing something") with Sample() as sample: sample.do_something() 运行结果: enter doing something exit 还有一种方法,可以简便的实现上下文管理器的功能:@contextlib.contextmanager 可以将一个函数变为上下文管理器 import contextlib @contextlib.contextmanager def file_open(file_name): print ("file open") yield {} print ("file end") with file_open("a.txt") as f_opened: print("file processing") 运行结果: file open file processing file end @contextlib.contextmanager内部会做一些逻辑,其实是利用了生成器的特性。

优秀的个人博客,低调大师

Python高级知识点学习(二)

深入类和对象 鸭子类型问:什么是鸭子类型?答:当看到一只鸟走起路来像鸭子,游泳像鸭子,叫起来也像鸭子,那么这只鸟就可以被看做鸭子。(所有的类或对象,都实现了共同的方法,方法名要一样,这样的话这些类就归为一种类型,在调用时同时调用同样的方法) 在java中,要实现多态,所有子类必须继承父类并重写父类的方法;在python中,python中对象和java不同,变量是动态的可以指向任何一个类型。 class Cat(): def say(): pass class Dog(): def say(): pass class Duck(): def say(): pass 三个类共同实现同一个方法且方法名相同,就实现了多态。Python多态比Java简单正是因为python是动态语言。 抽象基类abc模块 何为抽象基类?继续用java做比较,Python这里抽象基类可以当做java中的接口,java中是无法实现多继承的,java只能继承一个类,但是可以继承多个接口,接口是不能用来实例化的;所以Python里边抽象基类也是不能实例化的。 python是动态语言,动态语言是没有变量类型的,Python中变量只是个符号而已,它可以指向任何类型的对象。 所以在Python中也就不存在多态这种概念,我们可以赋值任何类型数据给Python中的变量,而且它是可以修改的,所以说它就不需要像java中一样去实现多态,因为本身从语言层面讲就是支持多态的语言。 动态语言和静态语言非常大的区别之一就是静态语言不需要我们指明变量类型,所以动态语言中也就少了编译时检查错误的环节,python中写错了代码只能在运行中发现错误。 不同魔法函数就赋予了类不同特性,和java非常大的区别就是不需要去继承某一个指定的类。 鸭子类型和魔法函数构成了Python语言的基础,也就是Python中的协议。我们只需要去实现指定的魔法函数,类就可以是某种类型的对象,不同魔法函数具有的特性不同,这种使用魔法函数事先约定好的做法我们都可以称之为一种协议。 抽象基类用途: 我们在某些情况之下希望判定某个对象的类型 我们需要强制某个子类必须实现某些方法 抽象基类用法: 在基础类中,我们去设定好一些方法,所有继承这个基类的类都必须覆盖抽象基类的方法, 抽象基类是无法实例化的 所有的抽象基类继承的必须是metaclass=ABCMeta 在做框架编程时,往往我们需要使用框架者在使用类时必须实现类中的一些方法,这时候可以使用抽象基类,举了例子: class CacheBase(metaclass=abc.ABCMeta): @abc.abstractmethod def get(self, key): pass @abc.abstractmethod def set(self, key, value): pass class RedisCache(CacheBase): pass redis_cache = RedisCache() 运行结果:TypeError: Can't instantiate abstract class RedisCache with abstract methods get, set在实例化RedisCache()这个时,就开始报错了,错误提示让我们必须实现get set方法。 补全这两个方法后运行就不报错了 class RedisCache(CacheBase): def set(self, key, value): pass def get(self, key): pass redis_cache = RedisCache() type和isinstance区别 尽量使用isinstance判断类型,避免使用type产生误差is 和 == 符号 区别: is用法判断id是否相同 ==用法判断值是否相等 类变量和实例变量(对象变量) 先看代码: class A: # 类变量 aa = 1 def __init__(self, x, y): # self是类的实例 # 实例变量 self.x = x self.y = y # 上边赋值后 x y 都属于实例了 不再属于类了 a是实例 A是类 aa是类变量 类变量在所有实例中是共享的 a = A(2, 3) A.aa = 11 a.aa = 100 # a实例新建一个属性 把aa放到a实例中 a.aa和A.aa是独立的 print(a.x, a.y, a.aa) print(A.aa) b = A(3, 5) print(b.aa) 运行结果: 2 3 100 11 11 解释代码: 新建了一个名为A的类,类中新建类属性aa = 1类中新建构造函数,绑定两个变量x y。 属性查找方式,向上查找,首先查找对象里有没有,再查找类中有没有类变量和实例变量是独立的存在 类变量在所有实例中是共享的 a.aa = 100:a实例新建一个属性 把aa放到a实例中 a.aa和A.aa是独立的。 建议以上代码反复测试加以记忆。

优秀的个人博客,低调大师

Python高级知识点学习(一)

image.png Python中一切皆对象 和Java相比,Python的面向对象更加彻底。 函数和类也是对象,是python的一等公民。 代码和模块也可以称之为对象。 python中的类也是对象,类可以理解为模板,根据这个模板去生成我们的对象,可以动态修改类的属性。 何为一等公民? 可以赋值给一个变量 可以添加到集合对象中 可以作为参数传递给函数 可以当做函数的返回值 (生成器应用) type、object、class之间的关系 类是由type来生成的一个对象,object是所有类都要继承的最顶层的一个基础类,type也是一个类,同时也是一个对象。 看代码片段一: a = 1 b = "abc" print(type(1)) print(type(int)) print(type(b)) print(type(str)) 打印出的结果: <class 'int'> <class 'type'> <class 'str'> <class 'type'> 代码片段二: class Student: pass class MyStudent(Student): pass stu = Student() print(type(stu)) print(type(Student)) print(int.__bases__) print(str.__bases__) print(Student.__bases__)# 打印Student基类 print(MyStudent.__bases__)# 打印Student基类 print(type.__bases__) print(object.__bases__) # 最顶层的类的基类为空 print(type(object)) 打印出的结果: <class '__main__.Student'> <class 'type'> (<class 'object'>,) (<class 'object'>,) (<class 'object'>,) (<class '__main__.Student'>,) (<class 'object'>,) () <class 'type'> 可以看到,类是由type来生成的一个对象。 上述代码建议反复阅读练习。 Python中常见的内置类型 首先说明对象的三个特征: 身份:也就是地址,通过id()函数查看地址 类型:int、str等 值:每个对象都有自己的值 常见内置类型: None(全局只有一个),Python解释器在启动时会用None生成一个None对象。 a = None b = None print(id(a) == id(b)) 打印结果: Ture 可以看到a,b是指向同一个对象(id相同)。 数值类型:int float complex(复数) bool。 迭代类型:可用for进行遍历 序列类型:list、bytes、range、tuple、str、array 等 映射类型:dict 集合类型:set、frozenset 上下文管理器:with语句 其他:class、实例 等等等。 Python中的魔法函数 问:什么是魔法函数? 答:双下划线开头,双下划线结尾的这些函数,通常称之为魔法函数。 例如: image.png 一般魔法函数不要自定义,使用 Python 提供的即可。 使用 Python 提供的魔法函数,为了增强类的特性。 代码:使用魔法函数之前 class Company(object): def __init__(self, employee_list): self.employee = employee_list company = Company(["tom", "bob", "jane"]) for i in company.employee: print(i) 打印结果: a b c 代码:使用魔法函数之后 class Company(object): def __init__(self, employee_list): self.employee = employee_list def __getitem__(self, item): return self.employee[item] company = Company(["a", "b", "c"]) 打印结果: a b c 可以看到__getitem__()这个魔法函数的功能。 定义了这个魔法函数后,实例化后的对象就隐含的变为可迭代对象(iterable)。 for循环其实是要拿到一个对象的迭代器,迭代器是需要实现__iter__这个方法才会有迭代器特性,Python语法会做一些优化,如果拿不到迭代器,就会尝试去对象中找__getitem__这个方法,如果有的话就会调用这个方法,一次一次直到将数据取完。这是python语言本身解释器会完成的功能。 魔法函数调用不需要显示调用,解释器会隐式调用。 Python的数据模型 魔法函数是Python数据模型的一个概念而已,因为网络上大家喜欢称之为魔法函数。 Python数据模型会增强对象的特性。 class Company(object): def __init__(self, employee_list): self.employee = employee_list def __getitem__(self, item): return self.employee[item] def __len__(self): return len(self.employee) company = Company(["a", "b", "c"]) print(len(company)) 结果: 3 __len__魔法函数增强了company对象的特性。 因为魔法函数很多,类似的魔法函数请大家自行去网上查找,并查看用法。

优秀的个人博客,低调大师

JavaScript—Ajax基础知识梳理(29)

Ajax用一句话来说就是无须刷新页面即可从服务器取得数据。注意,虽然Ajax翻译过来叫异步JavaScript与XML,但是获得的数据不一定是XML数据,现在服务器端返回的都是JSON格式的文件。 完整的Ajax请求过程完整的Ajax请求过程 1.创建XMLHttpRequest实例2.发出HTTP请求 3.接收服务器传回的数据4.更新网页数据 下面先看一个红宝书上给出的发起Ajax请求的例子,API的用法在后面章节给出。 var xhr = new XMLHttpRequest(); // 创建XMLHttpRequest实例 xhr.onreadystatechange = function(){ if (xhr.readyState == 4){ // 判断请求响应过程阶段,4 阶段代表已接收到数据 if (xhr.status >=200 && xhr.status < 300 || xhr.status == 304) { // 校验HTTP状态码 console.log(xhr.responseText); // 输出响应的文本 } else { console.error(xhr.status, xhr.statusText); // 打印其他HTTP状态码 } } }; xhr.open('get', 'example.txt', true); // 初始化xhr实例,或者说启动请求 xhr.send(null); // 设置HTTP请求携带参数,null为不带参数 Ajax请求过程详解 创建XMLHttpRequest实例从上面的的代码可以看出,创建一个XHR实例方式为: var xhr = new XMLHttpRequest(); 发出HTTP请求实例创建好后,首先需要启动一个HTTP请求,使用XHR的open()方法,open方法接受三个参数 XMLHttpRequest.open(method, url, isAsync) // 例如 xhr.open('get', 'http://www.baidu.com', true) 第一个参数为http请求使用方法,如('get','post'等),第二是参数是请求的url, 第三个参数代表是否异步发送请求(可选)。调用open()方法后会启动一个http请求,但它不会立即发送请求,处于待命状态。需要注意的是:请求的url必须要跟请求源域(origin)同域,也就是说协议、域名、端口号要一致,跨域请求要使用别的方法。接着调用send()方法就会发出这个http请求。 xhr.open('get', 'http://www.baidu.com', true) xhr.send(null) send()方法接受一个参数,为http请求发送的数据(通常用于'post'方法),如果为null,表示不发送数据。至此,一个异步的http请求就发送到了服务器。 接收服务器传回的数据3.1 发送同步请求 如果将open方法的第三个参数设为false,即为同步请求,当收到服务器的响应后,相应的数据会自动填充到XHR对象的属性中,主要包括以下四个: responseText:作为响应主体被返回的文本。 responseXML: 响应返回的XML文档,能接收到的前提是,响应的Content-Type字段的值为text/xml或者application/xml。 status: HTTP状态码。 statusText: HTTP状态码说明。 当客户端收到以上信息后,首先要判断HTTP状态码来确认响应是否成功,状态码在200-300之间表示请求成功,同时304代表请求资源未被修改,可使用浏览器本地缓存。如果成功就可以获取响应报文主体中的数据了。 xhr.open('get', 'http://www.baidu.com', false) xhr.send(null) if (xhr.status >=200 && xhr.status < 300 || xhr.status == 304) { // 校验HTTP状态码 console.log(xhr.responseText); // 输出响应的文本 } else { console.error(xhr.status, xhr.statusText); // 打印其他HTTP状态码 } 3.2 发送异步请求如果将open方法的第三个参数设为true,即为异步请求。那么就需要一个事件来通知程序异步请求的结果是否返回。XHR对象中的readyState属性,表示请求/响应整个过程所处的阶段,它有五个值分为对应五个阶段: 0:未初始化。未调用open()方法。1:启动。已经调用open()方法,但未调用send()方法。2:发送。已调用send()方法,但未收到响应。3: 接收。已经接收到部分响应数据。4:完成。已经接受到全部响应数据。 readyState的值每变化一次,都会触发一次readStatechange事件,我们定义一个事件处理函数onreadStatechange(),并监听readyState == 4状态,就可以得知响应数据已全部收到,并进行下一步操作。那么就是文章开头给出的代码: var xhr = new XMLHttpRequest(); // 创建XMLHttpRequest实例 xhr.onreadystatechange = function(){ if (xhr.readyState == 4){ // 判断请求响应过程阶段,4 阶段代表已接收到数据 if (xhr.status >=200 && xhr.status < 300 || xhr.status == 304) { // 校验HTTP状态码 console.log(xhr.responseText); // 输出响应的文本 } else { console.error(xhr.status, xhr.statusText); // 打印其他HTTP状态码 } } }; xhr.open('get', 'example.txt', true); // 初始化xhr实例,或者说启动请求 xhr.send(null); // 设置HTTP请求携带参数,null为不带参数 补充XHR中三个有用的事件 timeout事件当超出了设置时间还未收到响应,就会触发timeout事件,进而调用ontimeout事件处理程序。同时timeout也是XHR的一个属性,用于设置这个时间阈值。下面是用法: xhr.ontimeout = function() { alert('timeout!') } xhr.open('get', 'http://www.baidu.com', true) xhr.timeout = 1000 // 时间阈值设为1秒 xhr.send(null) load事件 load事件用于简化对readState值的判断,响应数据全部接收完毕后(也就是readState == 4)会触发load事件,使用onload事件处理函数进行后续操作,onload会接收一个event对象,它的target属性等于XHR对象,当然我们在定义这个事件处理函数时也可以不传入这个参数,来看下面的用法: var xhr = new XMLHttpRequest() xhr.onload = function () { if(xhr.status >=200 && xhr.status < 300 || xhr.status == 304) { console.log(xhr.responseText); // 输出响应的文本 } else { console.error(xhr.status, xhr.statusText); // 打印其他HTTP状态码 } } xhr.open('get', 'http://www.baidu.com', true) xhr.send(null) 这样就不用去关心readyState值的变化情况了。当然如果想在特定readyState值上做一些逻辑处理,还是要用之前的方法。 progress事件这个是很有用的一个事件,progress事件会在浏览器接收数据期间周期触发,代表整个请求过程的进度,它的事件处理程序onprogress接收一个event对象,event.target是XHR对象,另外event还有三个属性: lengthComputable:Boolean值,进度信息是否可用。position:已经接收到的字节数。totalSize:总共要接收的字节数,被定义在响应报文的Content-Length字段中。 如果响应报文中有Content-Length字段,那么我们就可以计算当前时刻响应数据的加载进度了,这也是之前看到的一个面试题。看下面的代码: xhr.onprogress = function(event) { if(event.lengthComputable) { console.log(`Received: ${(event.position/event.totalSize).toFixed(4)*100}%`); } } 其他还有很多有用的API,如FormData表单序列化,overrideMimeType()重写XHR响应的MIME类型等等

优秀的个人博客,低调大师

Python Flask学习知识点(七)

timg (11).jpg 静态文件访问原理 app文件夹下新建文件夹static,放入一张图片demo.jpg,然后访问服务器启动默认地址127.0.0.1:81/static/demo.jpg就可以访问到这张图片。 问:为什么Flask可以在任何代码不编写的情况下自动读取到static目录下的图片文件? 答:因为Flask对于静态文件是有默认值设置的,默认情况下,Flask认为静态文件夹的名字就叫ststic,并且位于应用程序的根目录下的,也就是app文件夹目录下。 image.png 问:为什么应用程序根目录是app目录而不是app上边的flaskDemo目录? 答:因为在实例化Flask核心对象是传入了一个参数,如下代码: def create_app(): app = Flask(__name__) app.config.from_object('app.secure') app.config.from_object('app.setting') register_blueprint(app) db.init_app(app) db.create_all(app=app) return app __name__这个参数决定了我们应用程序的根目录是app目录。 如果不想使用默认的static作为静态文件存储路径,可以通过更改配置来访问, app = Flask(__name__, static_folder='web/img') 更改成为这个路径,就要这样访问:127.0.0.1:81/img/demo.jpg, 还可以这么改: app = Flask(__name__, static_folder='web/img', static_path='') 但是我们一般还是使用Flask默认设置即可,如果确实有需求,具体使用详情请查阅官方文档。 静态文件放到蓝图中 之前说过,Flask里有两个层级: Flask核心对象:应用程序级别 蓝图 对于静态文件,也有两个级别: 应用程序static 蓝图static 如果你认为你的静态文件是针对你的蓝图的话,那么你其实是可以把静态文件注册到蓝图上边,而不是注册到应用程序上边。 image.png 蓝图的相关方法其实几乎就是复制了Flask核心对象的api,基本参数都是一致的。 蓝图注册静态文件夹: from flask import Blueprint # 蓝图 web = Blueprint("web", __name__, static_folder='', static_url_path='') 模板文件 模板就是html,但是和普通html不同,模板是没有数据的,它等待填充数据。 app文件夹下新建文件夹templates,新建html文件:test.html: image.png 同上边提到的static文件夹一样,我们可以自定义templates文件夹的位置,通过更改template_folder=参数来自定义templates文件夹的位置,例如,把templates文件夹移动到web文件夹下后需改动: 两种更改方法: Flask核心对象上更改:app = Flask(__name__, template_folder='web/templates') 在蓝图对象上更改:web = Blueprint("web", __name__, template_folder='templates') 现在要把视图函数中返回的数据填充到模板test.html中,使用Flask内置的方法:render_template() from flask import render_template @web.route('/test') def test(): r = { "name": "allen", 'age': 24 } r1 = { "name": "zhao", "age": 12 } return render_template('test.html', data=r, data1=r1) 模板语言 Jinja2 如何在模板中组织、解析相关数据 编辑test.html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>demo</h1> {{data.age}} {{data1.age}} </body> </html> 运行代码,浏览器输入127.0.0.1:8000/test image.png 可以看到,之前我们写在视图函数中的数据已经展示到页面了。 Flask为了让我们很好的在模板解析和展示数据,它引入了一个模板引擎,叫做Jinja2。 Jinja2有自己的语法,例如注释代码:{#hello word#},这里就把hello word注释掉了。 我们的pycharm默认是不会像写python代码一样智能提示Jinja2的语法,但是,更改设置即可: image.png Jinja2也叫做模板语言, Flask官方推荐我们使用Jinja2,大家也可以自己使用其他的模板语言。

优秀的个人博客,低调大师

Python Flask学习知识点(六)

timg (10).jpg image.png Flask多线程机制 发送请求和服务器处理请求的线程之间的关系? 客户端发送十个请求,Flask开启多少个线程处理请求?其实是由web服务器开启的多线程。 如果要上生产线,一般不会用Flask自带的web server。 对于一个web网站而言,必须有承受并发的能力。 单线程: 如果是单线程,只有当一个请求处理完成之后,才会处理下一个请求,所以这时候看起来就像是要排队一样 单线程下,当一个请求进来之后,Flask会实例化一个Request对象,用这个对象来装载请求信息,这时候只有一个实例化的request,当第一个请求结束后,Flask会再实例化一个Request对象来装载第二个请求,然后request变量又指向当前请求,那么这样众多用户就不会混乱。 多线程: werkzeug库下local模块下的Local对象,Flask就是用Local来做线程隔离的。 Local对象的本质就是用线程的id号作为字典的键这种基本原理实现的。 Flask中线程隔离栈LocalStack LocalStack 是实现线程隔离的栈结构,把Local封装了。 LocalStack需要使用push方法 LocalStack: Local特性 Stack特性:栈结构,只能取栈顶元素,先进后出 使用线程隔离的意义在于:使当前线程能够正确引用到他自己做创建的对象,而不是引用到其他线程做创建的对象 线程隔离对象 LocalStack 问:Flask使用LocalStack为了隔离哪个对象? 答:被线程隔离对象 RequestContext AppContext Flask核心对象全局只有一个。 看一段测试代码,测试下LocalStack线程隔离: import threading from werkzeug.local import LocalStack stack = LocalStack() stack.push('a') print('主线程top:', stack.top) def child(): print("子线程:", stack.top) stack.push('b') print('子线程:', stack.top) t = threading.Thread(target=child, name='demo') t.start() print('主线程top:', stack.top) 打印结果: 主线程top: a 子线程: None 子线程: b 主线程top: a 还有哪些是被线程隔离的对象? image.png 以上都是被线程隔离的对象。 ViewModel的基本概念 很多时候,我们的数据在提交给页面的时候需要做一些处理或者裁剪,这时就需要ViewModel层来做这件事,如图: image.png viewModel作用 裁剪 修饰 合并 app文件夹下新建文件夹view_models,这里就可以处理数据的裁剪、修饰、合并。 单页面与网站的区别 一个网站页面由哪几部分构成? JS CSS(静态文件) HTML模板 数据 网站 一般来讲,服务器端把数据返回到HTML模板中,称之为服务器渲染,然后返回到浏览器给用户,此时,客户端浏览器网页中的JS CSS起作用再一次发起请求渲染页面,这是一个完整的页面就处理完了。 image.png 单页面 浏览器去请求一个静态的html,html返回到客户端浏览器后,html里边的js css 发起请求,来填充数据。 image.png 单页面和普通网站有什么区别: 区别的第一种说法: 对于多页面普通网站而言,大多数情况下它的数据渲染或者说模板填充都是在服务器端进行的, 而对于单页面来说,他数据的渲染是在客户端进行的。 区别的第二种说法: 单页面业务逻辑也就是说数据运算主要集中在客户端用js去操作,而普通网站而言,绝大多数业务逻辑是在服务器,也就是视图函数中去进行的。

优秀的个人博客,低调大师

Python Flask学习知识点(四)

timg (8).jpg 上节讲到,视图函数可以以接受参数的形式来获取传入后台的参数,但是往往我们需要对参数进行校验,比如说请求一个10条数据,那么page=10,但是如果某些比较皮的小盆友传入一个page=10000,那服务器也要去数据库查询10000条记录返回吗?显然不能那么做,所以这就涉及到在Flask中做参数检查的工作。 WTForms参数验证 首先,安装这个第三方的插件wtformspip install wtforms 我们都知道,在web应用中,分层这个概念非常重要,MVC模式其实可以理解为就是分层,这里我们引入验证层这个概念。无论写任何的web应用,验证层都是非常重要的概念。 所以我们所有的参数校验工作,都不会直接写到视图函数中,而是都会放到验证层去做。 在app文件夹下新建forms文件夹,并新建book.py文件: image.png 编写book.py: from wtforms.validators import Length, NumberRange, DataRequired() from wtforms import Form, StringField, IntegerField class SearchForm(Form): q = StringField(validators=[DataRequired(), Length(min=1, max=30)]) page = IntegerField(validators=[NumberRange(min=1, max=99)], default=1) 解释这段代码: 使用wtforms提供的StringField对象来定义参数q的类变量 使用wtforms提供的IntegerField对象来定义参数page的类变量 wtforms内置了很多的验证对象来帮助我们快速的完成对参数的验证,而不需要手动编写验证函数。当然了,我们也可以自定义验证对象。 为了验证q参数,可以使用内置的验证对象:Length,验证q参数的长度,validators接受一个list,可以传入多个验证对象,这里我们验证q参数传入Length验证对象。 同样,验证page参数也是同样的原理,这里使用的三个内置的验证对象(NumberRange,Length,DataRequired),可以查阅文档了解详细的用法。 编写完验证层代码,在视图函数中调用,更改web文件夹下book.py: from flask import jsonify, request from flaskDemo.app.forms.book import SearchForm from . import web @web.route('/hello') def search(): form = SearchForm(request.args) if form.validate(): q = form.q.data page = form.page.data result = {"name": q, "valus": page} return jsonify(result) return jsonify({"error": 0}) 解释代码: 首先导入SearchForm并实例化为form对象,并且传入参数request.args,通过form.validate()的返回值判断是否符合验证器规定的结果。 这里讲一点,使用page = form.q.data这种方式获取q和page的值,而不直接使用q,是因为我们之前在验证层SearchForm中定义了page参数如果为空,使用1为默认值,所以我们要从form.q.data 这种拿到page参数。 看下效果,运行run.py启动,在浏览器中输入符合规则的urlhttp://127.0.0.1:8000/hello?q=demo&page=1 再输入不符合规则的urlhttp://127.0.0.1:8000/hello?q=demo&page=100 返回结果: image.png image.png 一个是成功,一个是失败。 因为之前我们在验证层中定义了page的最大值为99,所以如果输入100,就会返回错误。 再试一下不输入page参数:http://127.0.0.1:8000/hello?q=demo image.png 还是可以返回默认值。 继续,看下图: image.png debug调试过程中,看下form实例中的一个errors,这个errors就是当验证不通过时,wtforms给我们的一个错误提示,在一般情况下,如果参数验证不通过时是会抛出一个异常的,但是使用wtforms,它会把错误提示放到errors属性中而不抛出异常。 更改代码: def search(): form = SearchForm(request.args) if form.validate(): q = form.q.data page = form.page.data result = {"name": q, "valus": page} return jsonify(result) return jsonify({"error": form.errors}) 这里改为return jsonify({"error": form.errors})。 再运行代码输入URLhttp://127.0.0.1:8000/hello?q=demo&page=100得到如下: image.png 可见wtforms告诉我们为什么验证不通过。 这里也可以在SearchForm自定义返回的错误信息,只需更改为: class SearchForm(Form): q = StringField(validators=[DataRequired(), Length(min=1, max=30)]) page = IntegerField(validators=[NumberRange(min=1, max=99, message="传入的参数不符合要求")], default=1) 再运行代码: image.png 拆分配置文件 之前我们一直是把配置参数全部放到config.py中,但是这样的话会有一个问题,那就是如果我们把比较私密的配置(例如数据库地址以及密码)和普通的参数放在一起,势必会有安全风险,比如把代码传到了git上,所以最好把配置文件拆分为两种不同级别的,这里我们把config.py拆分为secure.py和setting.py,并且全部放到app文件夹下。 secure.py 用来存放数据库密码、账号还有我们后边提到的flask app key ,这样比较机密的信息,单独放配置文件中,还有就是开发环境和生产环境中的不同设置,比如 debug=True。 setting.py 用来存放不涉及到机密的,生产和开发环境一样的配置。 更改之前的代码,app文件夹下的__init__.py: def create_app(): app = Flask(__name__) app.config.from_object("app.setting") app.config.from_object("app.secure") register_blueprint(app) return app current_app 在Flask中,如果要在运行中读取配置文件中的参数,需要使用Flask核心对象app来查找,但是之前讲过,如果反复导入app,或造成循环导入,那么解决方法就是使用current_app,current_app其实就是指代的app, 例如,读取配置文件中的PER_PAGE变量: 因为之前我们做了这个操作: def create_app(): app = Flask(__name__) app.config.from_object("app.setting") app.config.from_object("app.secure") register_blueprint(app) return app 把setting.py和secure.py中的配置加到了Flask内置config对象中,所以要这样读取配置文件中的变量: current_app.config['PER_PAGE'] 欲知后事如何,请看下回分解,记得点个赞~感谢

优秀的个人博客,低调大师

ASP.NET资源大全-知识分享

API 框架 NancyFx:轻量、用于构建 HTTP 基础服务的非正式(low-ceremony)框架,基于.Net 及 Mono 平台。官网 ASP.NET WebAPI:快捷创建 HTTP 服务的框架,可以广泛用于多种不同的客户端,包括浏览器和移动设备。官网 ServiceStack:架构缜密、速度飞快、令人愉悦的 web 服务。官网 Nelibur:Nelibur 是一个使用纯 WCF 构建的基于消息的 web 服务框架。Nelibur 可以便捷地创建高性能、基于消息的 web 服务,使得你全面拥有 WCF 的强大能力。官网 WebAPI Contrib:帮助你提高 ASP.NET Web API 能力的开源项目集合。官网 应用框架(Application Frameworks) ASP.NET Boilerplate:现代 ASP.NET MVC web 应用程序的入门,包含最佳实践和最流行的工具。官网 Orleans:Orleans 框架提供了直接构建分布式、大规模计算应用的方法,无需学习和使用复杂的并行或扩展模型。官网 CoreFX:corefx 仓库包含了 .NET 核心功能库的实现(被称为“CoreFX”)。包含了 System.Collections、System.IO、System.Xml 以及诸多其它组件。目前构建并运行于 Windows 平台。你可以关注这个仓库,了解在未来的几个月内即将增加的对 Linux 和 Mac 的支持。官网 CSLA .NET:业务层开发框架http://www.cslanet.com。官网 Mono:Mono 是 ECMA CLI、C# 以及 .NET 的开源实现。官网 Mono-Addins:Mono.Addins 是一个通用框架,用于创建可扩展的应用程序,以及这些应用程序的扩展插件。官网 Spring.Net:Spring.NET 是一个开源的应用程序框架,可以便捷地创建企业级 .NET 项目。官网 应用模板(Application Templates) MVC.Template:ASP.NET MVC 5 入门项目模板。官网 ProjectScaffold:F# 基金会推荐的 .NET 解决方案的原型——包括文件系统的搭建、用于管理依赖的 Paket 以及用于自动化构建、测试的 FAKE。默认情况下,构建流程也会对文档进行编译,并生成 NuGet 程序包。官网 Side-Waffle:包含大量有用的 Web 和桌面开发模板。Side-Waffle Template10:带有设计模式的 Windows 10 模板。Template10 人工智能(Artificial Intelligence) AIMLBot(Program#):使用 C# 编写的一个小型、快速、兼容标准、易于定制的聊天机器人,基于 AIML (人工智能标记语言 Artificial Intelligence Markup Language)。官网 SIML:智能综合智能标记语言(Synthetic Intelligence Markup Language),下一代聊天机器人及数字助手语言。官网 程序集处理(Assembly Manipulation) dnSpy:dnSpy 是一个 .NET 程序集编辑器、反编译器和调试器,来自 ILSpy 分支。官网 Fody:织入(weaving).net 程序集的可扩展工具。官网 Mono.Cecil:Cecil 类库用于生成和检查 ECMA CIL 程序和库。官网 资源(Assets) Cassette:管理 .NET web 应用程序资源(脚本、css 和 模板)Cassette NodeAssets:.net 资源管理器,通过 SignalR 实时更新 css,也可以使用 NodeJS 编译器。官网 Bundler:编译和最小化 Less、Sass、Stylus、Css、JS、CoffeeScript、LiveScript文件。MVC集成了 MVC和 ServiceStack。官网 ClientDependency:压缩CSS与JS,提供WebForm与MVC版本。官网 SquishIt:让你轻松合并一些 css 和 javascript。官网 认证和授权(Authentication and Authorization) ASP.NET Identity:用于 ASP.NET 应用程序的新身份系统。官网 DotNetOpenAuth:OpenID、OAuth 和 InfoCard 协议的一个 C# 实现。官网 Logibit Hawk:一个 F#Hawk认证库。官网 IdentityModel:.NET 4.5 和 MVC4、Web API 身份和访问控制的辅助库。官网 IdentityServer:可扩展的 OAuth2 和 OpenID 连接提供程序框架。官网 OAuth:超轻量级 OAuth 1.0a 签名生成库,C# 编写。官网 自动构建(Build Automation) Psake:基于 .NET 的自动化构建工具,使用 PowerShell 编写。官网 FAKE:F# Make,一个跨平台自动构建系统。官网 Invoke-Build:PowerShell 自动构建和测试工具,灵感来自 Psake。官网 MSBuild:微软构建引擎(MSBuild)是 .NET 和 Visual Studio 的构建平台。官网 Cake:Cake(C# Make)使用 C# DSL 的跨平台自动构建系统。官网 缓存(Caching) CacheCow:ASP.NET Web API HTTP 客户端和服务器端缓存实现。官网 Akavache:一个异步、持久化的键值存储。官网 CacheManager:是用C#为.NET写的缓存管理抽象层,支持多种缓存工具,可以实现层次化的缓存。官网 CLI Command Line Parser:Command Line Parser 类库为 CLR 应用程序提供了一套简洁的 API,用于处理命令行参数及相关任务。官网 Fluent Command Line Parser:一个简单、强类型的 .NET C# 命令行解析库,交互方式流畅易用。官网 Power Args:PowerArgs 将命令行参数转换为 .NET 对象,便于程序使用。它还提供了大量可选的扩展,例如参数校验、自动生成使用帮助、tab 补全等等。官网 UnionArgParser:针对 F# 应用程序的声明式 CLI 参数和 XML 配置解析器。官网 CLR CoreCLR:coreclr repo 包含了完整的 .NET 核心运行时实现(称为“CoreCLR”)。它包括 RyuJIT、.NET GC、非托管代码交互(native interop)等诸多组件。它目前构建和运行于 Windows 平台。你可以关注这个仓库,了解未来的几个月内即将增加的对 Linux 和 Mac 的支持。官网 CMS Composite C1:一个 web 内容管理系统,着重在用户体验及适应性。官网 mojoPortal:MojoPortal 是一个可扩展、跨数据库、移动友好的 web 内容管理系统(CMS)和 web 应用程序框架,使用 C# ASP.NET 编写。官网 N2CMS:开源、轻量、代码优先的 CMS,可以无缝地集成到任何 MVC 项目中。官网 Orchard:免费、开源、专注社区的项目,目标是在 ASP.NET 平台上提供应用程序和可重用组件。官网 Piranha CMS:Piranha 是一个有趣、快速、轻量级的 .NET 框架,用于开发基于 cms 附带其它功能的 web 应用程序。它基于 ASP.NET MVC 和 Web 页面创建,完全兼容 Visual Studio 和 WebMatrix。官网 Umbraco:Umbraco 是一个免费开源的内容管理系统,基于 ASP.NET 平台构建。官网 代码分析和度量(Code Analysis and Metrics) CodeMaid:Visual studio 扩展,用于清理、挖掘和简化 C#、C++、F#、VB、PHP、JSON、XAML、XML、ASP、HTML、CSS、LESS、SCSS、JavaScript 和 TypeScript 代码。官网 StyleCop:StyleCop 使用一组风格和一致性规则,对 C# 源代码进行分析和强制性检查。官网 Gendarme:可扩展的、基于规则的工具,用于在 .NET 应用程序和类库中查找问题。官网 Metrics-Net:捕获 CLR 和应用程序级别的度量值。所以你知道它的功能。官网 编译器(Compiler) Bridge.NET:将 C# 编译成 JavaScript 的开源编译器http://bridge.net/。官网 ClojureCLR:从 Clojure 到 CLR 的转换,是 Clojure 项目的一部分。官网 F#:F# 编译器、核心库和工具——更安全、更快、代码更好的函数式编程语言。官网 FunScript:F# 到 JavaScript 的编译器,可以通过 TypeScript 类型提供程序使用 JQuery 等 JavaScript 库。官网 JSIL:CIL 到 Javascript 的编译器http://jsil.org/。官网 Mono-basic:Visual Basic 编译器和运行时。官网 Nemerle:Nemerle 是一个 .NET 平台高级静态类型编程语言。它提供函数式、面向对象式和命令式编程语言的特性。它拥有一个简单的类似 C# 的语法和强大的元编程(meta-programming)系统。官网Github Netjs:.NET 到 TypeScript 和 JavaScript 编译器。兼容可移植类库。你甚至可以使用 EXE 文件。官网 Roslyn:.NET 编译平台(“Roslyn”)提供开源的 C# 和 Visual Basic 编译器,包含丰富的代码分析 API。它可以使用和 Visual Studio 一样的 API 来构建代码分析工具。官网 VisualFSharp:Visual F# 编译器和工具。官网 压缩(Compression) SharpCompress:SharpCompress 是一个用于 .NET、Mono、Silverlight、WP7的压缩类库,可以解压rar、7zip、zip、tar、bzip2 和 gzip,提供单向读取和随机文件访问 API。支持对 zip/tar/bzip2/gzip 进行写入的实现。官网 DotNetZip.Semverd:一个开源项目,提供对 ZIP 文件处理的 .NET 类库和相关工具。 (分支自已经不再维护的DotNetZip)DotNetZip.Semverd SharpZipLib:一个 Zip、GZip、Tar 和 BZip2 的类库,完全由 C# 编写,面向 .NET 平台。官网 持续集成(Continuous Integration) TeamCity:可以直接使用的,可扩展、面向开发人员友好的构建服务器——开箱即用**。**[$]官网 CruiseControl.NET:一个自动化持续集成服务器,使用 .NET Framework 实现。官网 MyGet:为NuGet、NPM、Bower 和 VSIX 提供持续集成、部署、宿主程序包仓库的服务。[开源软件免费][$]官网 AppVeyor:.NET 持续构建和部署服务。[$][开源软件免费]官网 加密(Cryptography) BouncyCastle:和 .Net 的 System.Security.Cryptography 一起,在 CLR 上提供加密算法的实现。官网 HashLib:HashLib 包含了几乎所有你见过的哈希算法,它几乎支持所有东西并且非常容易使用。官网 libsodium-net:libsodium for .NET——一个安全加密库。官网 StreamCryptor:使用 libsodium 和 protobuf 对流进行加密和解密。官网 数据库(Database) BrightstarDb:BrightstarDB 是一个原生的 .NET RDF 三元组数据库(triple store)。官网 Event Store:开源的功能性数据库,支持使用 JavaScript 进行复杂事件处理。https://geteventstore.com官网 LiteDB:一个 .NET 的 NoSQL 单文件文档数据库。官网 RavenDB:支持 linq 的 .NET 文档数据库。官网 数据库驱动(Database Drivers) MySQL Connector:完全托管的 MySQLADO.NET 数据库提供程序、连接器。官网 Npgsql:Postgresql 的 .Net 数据提供程序。官网 MongoDB:MongoDB 官方 C# 驱动。官网 ServiceStack Redis:.NET 领先的 C# Redis 客户端。官网 StackExchange Redis:来自 StackExchange 的通用 redis 客户端。官网 Cassandra:DataStax 开发的 Apache Cassandra .NET 驱动程序。官网 Couchbase:couchbase 官方 .NET 客户端库,基于 Enyim memcached 客户端。官网 Firebird.NET:由C# 编写的 .NET 数据提供程序,提供对 Firebird API 的高性能原生实现。官网 反编译(Decompilation) ILSpy:ILSpy 是一个开源的 .NET 程序集查看器和反编译器。官网 JustDecompile Engine:JustDecompile反编译引擎。官网 de4dot:是一款强大的.NET程序集反混淆和脱壳工具(开源GPLv3)。官网 部署(Deployment) Unfold:基于 Powershell 的 .net web 应用程序部署解决方案。官网 DirectX SlimDX:为 .NET 应用程序提供的 DirectX 封装。官网 SharpDX:SharpDX 是一个开源项目,为 .Net 及所有 Windows 平台提供完整的 DirectX API,可以开发高性能的游戏、2D/3D图形渲染以及实时音频应用程序。官网 分布式计算(Distributed Computing) Project Orleans:Orleans 框架提供了直接构建分布式、大规模计算应用的方法,无需学习和使用复杂的并行或扩展模型。由微软研究院开发。官网 Akka.net:Akka.NET 是流行的 Java/Scala 框架 Akka 的 .NET 版本。它由社区提供,与 Typesafe(原始的 Java、Scala 版本的开发商)无关。官网 文档(Documentation) Sandcastle:Sandcastle 帮助文件生成器和 NDoc 类似。官网 SharpDox:一个 c# 文档工具。官网 Swashbuckle:向 WebApi 项目无缝地添加 swagger 文档(译者注:swagger 是一套用于生成、描述、展现 RESTful 风格 web 服务文档的框架和规范)。官网 NSwag:通过Swagger规范生成.NET、TypeScript的Web API客户端。官网 F# Formatting:F# 和 C# 项目的文档工具,文档生成自 F# 脚本文件、Markdown 文档、内嵌 XML 或 Markdown评论。官网 电子商务和支付(E-Commerce and Payments) Paypal Merchant SDK:Paypal Merchant官方.NET SDK。官网 NopCommerce:nopCommerce。开源的电子商务购物车(ASP.NET MVC)。官网 ServiceStack.Stripe:针对 stripe.com REST API 的强类型 .NET 客户端。官网 SmartStoreNET:免费 ASP.NET MVC 电子商务购物车解决方案。官网 Stripe.Net:Stripe.net 是针对http://stripe.com完整服务的 .net api。官网 BeYourMarket:BeYourMarket 是一个点对点的市场框架。官网Github Virto Commerce:Virto Commerce 是第二个版本,也是唯一的开源许可下的企业级别电子商务产品。Virto Commerce 基于 .NET 4.5,使用了 MVC、IoC、EF、Azure、Angular JS 等其他先进技术。它可以在微软的云平台(Azure)、亚马逊云服务(AWS)和企业内部部署。官网 环境管理(Environment Management) DNVM:.NET SDK 管理器,一组命令行工具,用于更新和配置需要使用的运行时环境(DNX)。官网 ETL Reactive ETL:Reactive ETL 使用 .NET 反应性扩展框架(reactive extensions) 重写了 Rhino ETL。官网 游戏(Game) MonoGame:一个用来创建跨平台游戏的强大框架。官网 CocosSharp:CocosSharp 是 Cocos2D 和 Cocos3D API 的 C# 实现版本,可以在所有支持 MonoGame 的平台上运行。官网 Duality:Duality 是一个 2D 游戏开发框架。专注于功能的模块化,自带一个可视化编辑器。官网 Paradox:Paradox 游戏引擎。官网 地理信息系统(Gis) NetTopologySuite:一个 在 .NET 平台上实现快速、可靠的 GIS 系统解决方案。官网 SharpMap:一个易于使用的地图库,可以用于 web 和桌面应用程序。官网 Git工具(Git Tools) Bonobo Git Server:Bonobo Git Server for Windows 是一个 web 应用程序,可以安装在你自己的 IIS 上,用于管理和连接你的 git 仓库。官网Github GitExtensions:GitExtensions 包含资源管理器扩展、Visual Studio 2008/2010/2012/2013 插件和一个独立的 Git 仓库工具。官网Github GitLink:让用户可以单步调试托管在 GitHub 或 BitBucket 上的代码。官网 GitVersion:根据你的 Git 仓库的状态生成一个语义化版本号(Semantic Version Number)。官网 LibGit2Sharp:LibGit2Sharp 带来了 libgit2 所有的功能和速度,是一个本地 Git 实现,可以运行在 .Net 和 Mono 平台。官网 NGit:NGit 是 JGit 移植到 C# 的版本。官网 posh-git:Git 的 PowerShell 环境。官网 图形(Graphics) Oxyplot:OxyPlot 是一个 .NET 跨平台绘图库。官网 OpenTK:Open Toolkit 是一个封装了 OpenGL、OpenCL 和 OpenAL 的 高级底层 C# 开发库。官网 NGraphics:NGraphics 是一个 .NET 跨平台矢量图形渲染库。官网 GUI MahApps.Metro:用于创建 Metro 风格 WPF 应用的工具箱。官网 Callisto:用于 Windows 8 XAML 应用的控件工具箱。包含若干 UI 控件,让你更容易地创建符合 Windows UI 风格规范的Windows 商店应用。官网 ObjectListView:ObjectListView 使用 C# 封装了 .NET 的 ListView 控件。它使得 ListView 更加易用,并且加入了一些新特性。官网 DockPanelSuite:灵感来自 Visual Studio 的停靠窗口(docking)类库,用于 .NET WinForm 应用。官网 AvalonEdit:在 SharpDevelop 中使用,基于 WPF 的文本编辑器组件。官网 XWT:跨平台 UI 工具箱,用于创建 .NET 和 Mono 桌面应用程序。官网 Gtk#:Gtk# 是 Gtk+ GUI 工具箱的 Mono/.NET 版本,绝大多数 Mono 中的 GUI 应用都基于它构建。官网 MaterialDesignInXamlToolkit:用于创建 Material Design 风格 WPF 应用的工具箱。官网 Eto.Forms:跨平台的 GUI 框架,用于 .NET 和 Mono 下的桌面和移动应用程序。官网 Dragablz:可拖拽、可分离(tearable,译者注:即拖拽标签页成为独立窗口)的 WPF 标签页控件(类似 Chrome)。支持布局和主题,包含兼容 MahApps 和 Material Design 的主题。官网 Fluent.Ribbon:Fluent Ribbon Control Suite 是一个在 WPF 中实现 Office 和 Windows 8 风格的 Ribbon 库。官网 HTML 和 CSS(HTML and CSS) AngleSharp:支持构建完整的 HTML5 DOM 和 CSS3 模型。官网 CsQuery:jQuery 风格的HTML5 解析器,可与 DOM 交互。官网 dotless:ruby Less CSS 库的 .NET 移植版本。官网 ExCSS:C# 的 CSS3 解析器开发库。官网 FluentBootstrap:让ASP.NET MVC 和 WebPages 更容易使用 Boostrap CSS 框架。官网 HtmlAgilityPack:一个灵活的 HTML 解析器,可以对 DOM 进行读写,支持 XPATH 和 XSLT。官网 Jumony:类似HtmlAgilityPack框架,性能有改善。官网 HTTP Http.fs:[F#]中的一个函数式 HTTP 客户端。官网 RestSharp:.NET 下简单的 REST 和 HTTP API 协议客户端。官网 EasyHttp:C# Http开发库。官网 Refit:Xamarin 和 .NET 下自动生成强类型的 REST 库。官网 RestEase:类型安全且易于使用的 REST API 客户端库,简单可定制。大部分灵感来自 Refit。官网 IDE SharpDevelop:用于 .NET 编程语言的免费 IDE。官网 MonoDevelop:MonoDevelop 是一个跨平台的 IDE,主要面向 Mono/.NET 开发者。官网 Visual Studio Express:用于 .NET 开发的免费、轻量版本的 Visual Studio。官网 Visual Studio Community:功能完整的免费 IDE。官网 Waf DotNetPad:简单快速的代码编辑器,让开发 C# 或 Visual Basic 充满乐趣。官网 Visual Studio Code:非常棒的编辑器,来自微软,基于 GitHub Atom。官网 Rider:跨平台.Net IDE。官网 图像处理(Image Processing) ImageResizer:在图片 URL 后面增加命令,在几毫秒内获取修改后的版本,支持实时的对图片进行缩放、编辑。官网 ImageProcessor:开源 .NET 库,用于实时处理图片。官网 DynamicImage:高性能开源图片处理库,用于 ASP.NET。官网 MetadataExtractor:从图片中提取 Exif、IPTC、XMP、ICC 等其它元数据信息。官网 Emgu CV:OpenCV 的 .NET 跨平台封装。官网 安装工具(Install Tools) Wix Toolset:强大的工具集,用于创建你自己的 Windows 安装程序。官网 Squirrel:Squirrel 即是一套工具也是一个类库,可以无安全管理 Windows 桌面程序的安装和更新。官网 国际化(Internationalization) i18n:ASP.NET MVC 智能国际化工具。官网 互操作(Interoperability) CefSharp:Chromium Embedded Framework 的 .NET 支持(WPF 和 WinForm)。官网 CppSharp:在 C# 中平滑使用 C++ API 的工具。官网 Sharpen:Sharpen 是 db4o 编写的 Eclipse 插件,可以让你把 Java 项目转换为 C#。官网 CXXI:C++ 互操作框架。官网 IoC Castle Windsor:Castle Windsor 是一个用于 .NET 和 Silverlight 的成熟的 控制反转(IoC) 容器。官网 Unity:轻量级、可扩展的依赖注入容器,支持构造函数、属性和方法调用注入。官网 Autofac:令人着迷的 .NET IoC 容器。官网 Ninject:.net 依赖注入的忍者。官网 StructureMap:.Net 最早的 IoC/ID 容器。官网 Spring.Net:Spring.NET 是一个开源应用程序框架,可以便捷地创建企业级 .NET 应用。官网 LightInject:一个超轻量级 IoC 容器。官网 TinyIoC:单文件、简单、跨平台的 IoC 容器。官网 日志(Logging) Essential Diagnostics:为内置System.Diagnostics 命名空间扩展功能,提供更灵活的日志功能。官网 NLog:先进的 .NET 和 Silverlight 日志工具。官网 ELMAH:ELMAH 官方网站。官网 Elmah MVC:MVC 版 Elmah。官网 Logary:Logary 是一个 mono 和 .Net 平台下高性能、多目标的日志、度量、追踪和健康检查库。支持多目标,为微服务构建。官网 Log4Net:Apache log4net 工具库能够帮助程序员向多种不同的目标输出日志语句。官网 Serilog:一个 NoSQL 时代下简单直接的日志库。将多个优秀的传统结构化分析日志功能合并到一个易于使用的程序集中。官网 StackExchange.Exceptional:Stack Exchange 网络使用的错误处理程序。官网 Semantic Logging Application Block (SLAB):为内置 System.Diagnostics.Tracing 命名空间(EventSource类)扩展功能,支持将日志记录到多个容器中,包括 Azure 表存储、数据库、文件(JSON、XML、文本文件)。通过 ETW 支持进程内和进程外的日志记录,支持 Rx 进行实时的事件过滤和聚合。官网 Exceptionless:一个免费开源分布式系统的日志收集框架,它可以应用在基于 ASP.NET,ASP.NET Core,Web Api,Web Forms,WPF,Console,MVC 等技术栈的应用程序中,并且提供了Rest接口可以应用在 Javascript,Node.js 中。官网Github 机器学习和数据科学(Machine Learning and Data Science) Accord.NET:机器学习框架,包含了音频和图像处理的库(计算机视觉、计算机听觉、信号处理和统计)。官网 Accord.NET Extensions:高级图像处理和计算机视觉算法扩展。官网 AForge.NET:为计算机视觉和人工智能领域的开发者和研究人员提供的框架(包括图像处理、神经网络、遗传算法、机器学习、机器人科学)。官网 Deedle:处理探索性数据的数据帧和时序库,支持 C# 和 F#。官网 FsLab:数据科学和机器学习库的集合,支持 F# 和 .NET。官网 numl:包含最流行的监督学习和无监督学习算法,尽量减少创建预测模型时的冲突。官网 R Provider:将 R 语言包和函数封装为类型安全的类型提供程序供 F# 调用。官网 F# Data:F# 类型提供程序,访问 XML、JSON、CSV 和 HTML 文件(基于样例文档),以及 WorldBank 数据。官网 Markdown 处理(Markdown Processors) MarkdownSharp:C# 实现的开源 Markdown 处理器,在 Stack Overflow 中使用。官网 F# Formatting:用于生成 F# 和 C# 项目文档的工具。该工具库的核心组件中包含了可扩展的 Markdown 解析器。官网 CommonMark.NET:CommonMark 规范的 C# 实现,用于将 Markdown 文档转换为 HTML。为最佳性能和可移植性进行了优化。官网 邮件(Mail) FluentEmail:System.Net.Mail 的一个流式(Fluent)封装,支持 razor 模板引擎。官网 MailKit:完整的跨平台的邮件协议栈,包括 IMAP、POP3、SMTP,支持验证等特性。基于 MimeKit 构建。官网 MimeKit:跨平台 .NET MIME 创建和解析库,支持 S/MIME、PGP、TNEF 和 Unix mbox spools。官网 PreMailer.Net:一个 C# 开发库,将你的样式表嵌入到内置的 style 属性中,最大限度支持邮件客户端。官网 数学(Mathematics) MathNet:Math.NET 是一个开源项目,旨在创建和维护涵盖基础数学在内的工具集,面向高级和日常需要使用此类功能的 .Net 开发人员。官网 多媒体(Media) TagLib#:TagLib#(即 taglib-sharp)是一个读写媒体文件元数据的库,支持视频、音频和照片格式。官网 度量(Metrics) C# StatsD Client:Etsy StatsD 服务器的 C# 客户端。官网 App Metrics:开源跨平台 .NET 报表度量开发库。官网、GitHub 微框架(Micro Framework) .NET Micro Framework Interpreter:Microsoft® .NET Micro Framework(NETMF)是一个在 Visual Studio 中提供为小型设备上编写嵌入式应用的框架。官网 杂项(Misc) .NET Fiddle:在浏览器中编写、编译并运行 C# 代码。相当于 C# 版本的 JSFiddle。官网 AzureCrawler:从 Angular、Ember、Durandal 或任何 JavaScript 应用中获取 HTML 快照。官网 BitSharp:C# 比特币节点。官网 CSScript:CS-Script 是一个基于 CLR 的脚本系统,使用 C# 作为编程语言。CS-Script 目前针对微软的 CLR 实现(.NET 2.0/3.0/3.5/4.0/4.5)并完整支持 Mono。附带很多附加特性,比如脚本宿主。官网 CsvHelper:帮助读写 CSV 文件的开发库。官网 FluentValidation:一个小型的 .NET 校验库,使用流式接口和 lambda 表达式构建校验规则。官网 Humanizer:Humanizer 能够在 .NET 平台上满足所有针对字符串、枚举、日期、时间、时间范围、数字等类型数据的操作和显示要求。官网 LINQPad:一个 C#/VB/F# 的便签本,能够立即执行任何表达式、语句块或程序,带有富文本显示等有用的特性。同样可以让你使用 LINQ 进行交互性数据库查询。 [$](译者注:也有免费许可,但是功能受限)。官网 Polly:快捷便利的异常处理策略,例如 重试、始终重试、等待并重试或断路(Circuit Break)等行为。 (.NET 3.5、4.0、4.5、PCL、Xamarin)官网 Rant:Rant 程序文本生成 DSL(领域特定语言)。官网Github ScriptCS:使用文本编辑器、nuget 和强大的 Roslyn 来编写 C# 应用!官网 EntityFramework-Plus:Entity Framework 扩展,提供工具类、Bulk 操作、批处理/批量更新、查询缓存/过滤器/Future、审计等功能。官网、GitHub MVVM Caliburn.Micro:小型但功能强大的框架,可以用来给所有 XAML 平台创建应用。它对 MV* 模式的强大支持可以让你快速构建你的解决方案,与此同时不必牺牲代码质量和可测试能力。官网 MVVM Light Toolkit:该工具箱主要是用来加速创建和开发 MVVM 应用,适用于 WPF、Silverlight、Windows Store(RT)和 Windows Phone 平台。官网 Catel:Catel 是一个应用开发平台,主要着眼在 MVVM(WPF、Silverlight、Windows Phone 及 WinRT)以及 MVC(ASP.NET MVC)。Catel 的核心部分包含 IoC 容器、模型、校验、备忘录模式(memento)、消息中介(message mediator)、参数检查等。官网 UpdateControls:Update Controls 不需要你实现 INotifyPropertyChanged 接口或声明一个 DependencyProperty。可以将控件直接关联到 CLR 属性,这使得它完美贴合 MVVM 模式。官网 ReactiveUI:一个 .NET 下的 MVVM 框架,集成了反应性扩展框架(Rx),允许开发者使用 WPF、Windows Store Apps、WP8 或 Xamarin 创建优雅的、可测试的应用。官网 Okra App Framework:一个以 app 为中心的 Windows 8.1 MVVM 框架,融合依赖注入,包含一套完整的 Visual Studio MVVM 模板。官网 WPF Application Framework (WAF):一个轻量级的框架,能够帮助你创建结构优雅的 WPF 应用。支持你使用分层架构和 MVVM 模式。官网 MVVMCross:跨平台mvvm 移动开发框架,针对 WP7 和 WP8 的 WPF/Silverlight、Android 的 Mono、iOS 的 MonoTouch 以及 WPA8.1/Windows 8.1 商店应用的 Windows Universal 项目。它使用可移植类库(PCL)来支持可维护的跨平台 C# 原生应用。官网 Stylet:最小化 MVVM框架(参考 Caliburn Micro),包含了良好的文档、高覆盖率的测试以及自带的 IoC 容器。官网 Gemini:类似 Visual Studio Shell 的 IDE 框架。基于 WPF、AvalonDock 和 Caliburn Micro 构建。官网 Office ClosedXML:ClosedXML 能够让开发人员更便捷地创建 Excel 2007、2010 文件。官网 NPOI:该项目是 .NET 版本的 POI 项目,原始的 Java 版本位于http://poi.apache.org/。官网 EPPlus:EPPlus 是一个 .net 类库,用于读写 Open Office Xml 格式的 Excel 2007、2010 文件(xlsx)。官网 Open XML SDK:Open XML SDK 是一个开源库,用于处理 Open XML 文档(包括 DOCX、XLSX 和 PPTX)。官网 ORM Entity Framework:对象关系映射器(ORM)框架,让 .NET 开发人员使用领域特定的对象来处理关系型数据。官网 BL Toolkit:.NET 平台的业务逻辑工具箱。官网 Dapper:一个超小型、快捷轻便的 ORM 框架。官网 Dapper Extensions:小型类库,对 Dapper 的功能进行补充,为你的简单传统 CLR 对象提供基础的 CRUD(Get、Insert、Update、Delete) 操作。官网 NHibernate:NHibernate 对象关系映射器(移植自 Java 平台的 Hibernate)。官网 Fluent NHibernate:便捷、无需使用 XML、编译安全、自动化、基于约定命名的 NHibernate 映射库。官网 FluentMigrator:.net 下的便捷的迁移框架。官网 ServiceStack.OrmLite:轻量、简单、快速、基于命名约定的 POCO ORM。官网 Massive:小型、令人愉悦的数据访问工具,始终关爱你直到永远。官网 LINQ to DB:最快的 LINQ 数据库访问库,简单、轻量、快速、类型安全,在你的对象(POCO)和数据库之间搭建桥梁。官网 包管理(Package Management) NuGet:.NET 包管理器。官网 MyGet:为 NuGet、NPM、Bower 和 VSIX 提供程序包仓库宿主,同样提供 CI 服务。开源软件免费[$]官网 Paket:.NET 的一个包依赖管理器,支持 NuGet 包和 GitHub 仓库。官网Github PDF ITextSharp:iText 是一个PDF库,用于创建、修改、检查和维护 Portable Document Format(PDF)格式的文档[$]开源软件免费官网 Profiler MiniProfiler:一个简单但有效的小型 profiler,用于 ASP.NET 网站。官网 Glimpse:开源 web 诊断平台。官网 推送通知(Push Notifications) PushSharp:服务器端的推送通知类库,支持 iOS、OSX、Android、Chrome、Windows Phone、Windows 8、Backberry 和 Amazon 设备。官网 队列(Queue) NServiceBus:.NET 平台下最流行的服务总线。官网 RabbitMQ.NET:AMQP 客户端的 C# 实现,通过 WCF 绑定到已有的 AMQP 服务。官网 NetMQ:NetMQ 是 ZeroMQ 纯 C# 移植版本。官网 MassTransit:MassTransit 是一个精简服务总线(lean service bus)的实现,使用 .NET Framework 来构建松耦合应用程序。官网 Rebus:Rebus 是一个 .NET 平台的精简服务总线和 NServiceBus、MassTransit类似,只不过更加精简。官网 EasyNetQ:易于使用的 RabbitMQ .NET API。官网 Warewolf ESB:易于使用的服务总线和微服务平台,可以在一个可视化 IDE 中便捷的创建应用和服务。官网 CAP:用于处理分布式事务的 .Net 标准开发库。支持 EventBus,轻量级、高效且易于使用。官网 响应式编程(Reactive Programming) Rx.NET:Reactive Extensions (Rx)库使用观察者序列(observable sequences)和 LINQ 风格的查询操作,来进行异步和基于事件的程序开发。官网 Dynamic Data:用于集合的响应式编程框架。官网 计划调度(Scheduling) QuartzNet:Quartz 是 .NET 平台的企业级调度器。官网 Hangfire:在 ASP.NET 应用中,超简单地实现自主引导(fire-and-forget)、延迟和周期重复任务。高级版需要收费。官网 Hangfire.Redis.StackExchange:Hangfire的redis扩展库,基于StackExchange.Redis的开源实现。官网 Azure WebJobs:Azure WebJobs 是Azure中App Services一个附属服务,为Azure中运行的Web App提供后台运行环境(支持多种语言编写Job),有.NET的SDK开源,并且可以直接添加扩展也开源。官网 SDK 和 API 客户端(SDK and API Clients) AWS SDK:AWS SDK for .NET 让 .NET 开发者可以便捷地操作 Amazon Web Services。官网 Azure PowerShell:一组 PowerShell 命令行,让开发者和管理员开发、部署和管理 Microsoft Azure 应用。官网 Octokit.NET:.NET 平台下的 GitHub API 客户端库。官网 DropNet:Dropbox API 客户端开发库。官网 搜索(Search) Elasticsearch .NET:Elasticsearch.Net & NEST。官网 PlainElastic.Net:ElasticSearch 的一个简单的 .Net 客户端。官网 SolrNet:.Net 平台下的 Solr 客户端。官网 Lucene.net:Lucene.Net 是 Lucene 搜索引擎库的移植,使用 C# 编写,面向 .NET 环境的用户。官网 序列化(Serialization) Protobuf.NET:Protocol buffers 是 Google 使用的二进制序列化格式,在 Google 数据通讯中大量使用。官网 Json.NET:.NET 平台下流行的、高性能 JSON 框架。官网 ServiceStack.Text:在 servicestack.net 中使用的 JSON、JSV、CSV 文本序列化器。官网 Msgpack-Cli:MessagePack 的 CLI 实现。官网 Jil:.NET 平台下快速的 JSON 序列化器,基于 Sigil (在 StackOverflow 中使用)。官网 ProtoBuf:根据 .proto 规范,为 protocol buffer 序列化内容生成 C# 代码。官网 F# Data:F# 类型提供程序,访问 XML、JSON、CSV 和 HTML 文件(基于样例文档),以及访问 WorldBank 数据。官网 Bond:跨平台框架,用于处理系统化(schematized)数据。支持跨平台的序列化、反序列化,以及强大的通用机制来高效处理数据。官网 状态机(State machines) Stateless:直接使用 .NET 代码创建一个状态机和轻量的基于状态机的工作流。官网 Automatonymous:.Net 平台的状态机库,允许你编写流式API风格的状态机。官网 静态网站生成(Static Site Generators) Pretzel:.NET 平台下的网站生成工具(包含后续的一些功能)。官网 Sandra.Snow:.NET 平台的静态网站生成工具,借鉴 Jekyll。官网 Wyam:简单易用、高度模块化、拥有强大配置能力的静态网站生成工具。官网 风格指南(Style Guide) C# Style Guide:StackOverflow 上的C#风格指南 Q & A。官网 C# Coding Conventions:MSDN 官方的 C# 代码约定。官网 模板引擎(Template Engine) RazorEngine:基于微软 Razor 解析器引擎的开源模板引擎。官网 Nustache:无逻辑模板的开源库。官网 DotLiquid:Ruby Liquid 模板语言的 C# 移植版本。官网 测试(Testing) AutoFixture:AutoFixture 是一个用于 .NET 的开源框架,用于简化单元测试中的设置(Arrange)阶段。官网 FakeItEasy:.NET 平台的一个简单的 mocking 库。官网 Fluent Assertions:一组 .NET 扩展方法,可以让你更自然地指定 TDD 或 BDD 风格测试的期望值。官网 Fuchu:F# 的单元测试库,通过 tests-as-values 机制让你更容易创建领域特定语言(DSL)。官网 Machine.Specifications:Machine.Specifications (MSpec)是一个上下文、规范框架,忽略了语言本身的干扰,简化了测试。官网 Moq:.NET 平台下最流行和友好的 mocking 框架。官网 NBuilder:快速创建测试对象。官网 NSubstitute:一个友好的 .NET mocking 框架。官网 NUnit:官网 Rhino Mocks:.NET 平台的动态 Mocking 框架。官网 Shouldly:Shouldly 是一个断言(assertion)框架,主要功能是在断言失败时,给出简单明了并且友好的错误信息。官网 SpecFlow:将业务需求绑定到 .Net 代码。官网 xUnit:xUnit.net 是一个 .NET 平台下免费、开源、专注社区的单元测试框架。官网 BenchmarkDotNet:功能强大的基础测试 .NET 开发库。官网、GitHub 交易(Trading) Lean:Lean 引擎是一个开源的,完全由 C# 托管代码编写的交易算法引擎,用于桌面和云端。官网Github StockSharp:交易和算法交易(algorithmic trading)的开源平台(用于股票市场、外汇市场、比特币和期权交易)。官网 Visual Studio 插件(Visual Studio Plugins) Web Essentials:Web Essentials 为 Visual Stduio 扩展了大量的特性,提供了 web 开发人员盼望多年的功能。官网 VsVIM:Visual Studio 中的 VIM。官网 Nuget Package Manager:NuGet 是微软开发平台(包括 .NET)的包管理器。官网 SideWaffle:Visual Studio 2012、2013 中的一组项目模板集合,让 web 开发人员更加轻松。官网 Resharper:Visual Studio 开发人员生产力工具[$]官网 Refactoring Essentials:开源 C# 和 VB.NET 重构扩展,包括代码最佳实践分析器。官网 CodeContracts:.NET CodeContracts 工具源代码。官网 Git Diff Margin:在 Visual Studio 滚动条区域实时显示当前文件在 Git 上的差异。官网 Productivity Power Tools:一组 Visual Studio 专业版(及更高版本)的扩展,用于提高开发人员的生产力。官网 Web 框架(Web Frameworks) ASP.NET MVC:ASP.NET 是一个免费的 web 框架,用于创建优秀的 web 站点和应用程序。官网 FubuMVC:.NET 平台下前端控制器(front-controller)风格的 MVC 框架。官网 NancyFx:在 .Net 和 Mono 平台上创建 HTTP 服务的一个轻量级、非正式的框架。官网 IISNode:在 IIS 中宿主 NodeJS 应用程序。官网 Suave.IO:一个框架/库/web 服务器,当你看到你使用优美的 F# 编写的代码提前完成了你的项目时,它的存在会让你喜极而泣。(一个用 F# 编写 Web 应用的框架和服务器端)官网 Web 服务器(Web Servers) EmbedIO:基于 Mono 编写的跨平台的 Web 服务器。官网 XSP:Mono 中的 ASP.NET 宿主服务器。该模块包含了 Apache 模块、FastCGI 模块,可以用于挂载到其它 web 服务器或是作为一个测试用的独立服务器存在(类似微软的 Cassini 项目)。官网 Jexus:强劲、坚固、免费、易用的Linux ASP.NET服务器。官网 WebSocket SignalR:ASP.NET 库,开发者可以通过它在 web 应用程序中非常简单地实现实时功能。官网 Fleck:Fleck 是一个 C# 实现的 WebSocket 服务器。分支自 Nugget 项目。官网 Websocket-Sharp:WebSocket 协议的 C# 实现,包含客户端和服务器端。官网 XSockets:提供了一组工具,可以在微软 .NET 等平台上构建一个实时应用程序。官网 WebSocket4NET:.NET 2.0+、Xamarin、Mono、Silverlight、Windows Phone 以及 WinRT 下的 WebSocket 客户端。官网 SuperSocket:一个轻量级, 跨平台而且可扩展的 .Net/Mono Socket 服务器程序框架。官网 Windows 服务(Windows Services) TopShelf:一个简单的服务宿主框架,使用 .NET 构建 Windows 服务。官网 通讯框架(Communication Frameworks) DotNetty:一个快速开发高性能、高可靠性的非阻塞的事件驱动网络应用框架。官网 Helios:一套高性能的Socket通信中间件。官网 enode: 一个用来开发DDD、CQRS、EDA 以及事件驱动应用程序的框架。官网 其他列表(Other Lists) .NET-libraries-that-make-your-life-easier:开源的 .NET 库,让你的生活更加轻松、 awesome-LINQ:一组精心挑选的超棒的 LINQ 类库、工具等。 GitHub 主页:https://github.com/jobbole/awesome-dotnet-cn

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册