git 放弃本地修改

Look1: git checkout . #本地所有修改的。没有的提交的,都返回到原来的状态 git stash #把所有没有提交的修改暂存到stash里面。可用git stash pop回复。 git reset --hard HASH #返回到某个节点,不保留修改。 git reset --soft HASH #返回到某个节点。保留修改 git reset HEAD^ #撤销上一次commit,回到没有add的状态 git clean -df #返回到某个节点 git clean 参数 -n 显示 将要 删除的 文件 和 目录 -f 删除 文件 -df 删除 文件 和 目录 也可以使用: git checkout . && git clean -xdf CSDN ↩︎

August 9, 2019 · 1 min · Egbert Ke

为什么使用object.__setattr__

werkzeug 0.6.1中Local的初始化是这样的: class Local(object): __slots__ = ('__storage__', '__lock__') def __init__(self): object.__setattr__(self, '__storage__', {}) object.__setattr__(self, '__lock__', allocate_lock()) 我当时很奇怪为什么要用object.__setattr__, 而不是直接用self.__storage__, 当我直接用self.__storage__ = {}实现的时候才发现问题: self.__storage__会调用__setattr__,而__setattr__中会调用self.__lock__.acquire(),因为此时self.__lock__还没有定义, 所以会调用self.__getattr__,而self.__getattr__中也会调用self.__lock__.acquire(), 此后就会一直调用self.__getattr__,最终导致StackOverflow。 而显示调用object.__setattr__就不会触发Local内部的__setattr__,从而避免上述情况。而且两者的效果是一样的,object.__setattr__的第一个参数是self,也就是这个实例,所以并不用担心是不是在父类定义了一个公共属性。 类似的还有使用object.__getattribute__的情况,一般也是为了避免无限递归。

July 23, 2019 · 1 min · Egbert Ke

理解werkzeug中的Local对象

ThreadLocal是线程级别的local,如果在greenlet或者协程这种微线程环境下,或者在多个请求共用一个线程的情况下,线程级别是不够的。ThreadLocal是thread-safe和thread-specific的, 而有些情况需要greenlet-safe和greenlet-specific或者request-safe和request-specific。 werkzeug 0.1版中Local的实现是这样的: try: from py.magic import greenlet get_current_greenlet = greenlet.getcurrent del greenlet except (RuntimeError, ImportError): get_current_greenlet = lambda: None try: from thread import get_ident as get_current_thread from threading import Lock except ImportError: from dummy_thread import get_ident as get_current_thread from dummy_threading import Lock from werkzeug.utils import ClosingIterator def get_ident(): """ Return a unique number for the current greenlet in the current thread. """ return hash((get_current_thread(), get_current_greenlet())) class Local(object): def __init__(self): self....

July 18, 2019 · 2 min · Egbert Ke

ThreadLocal

TheadLocal 用于多线程环境下,线程之间可以使用相同的变量,而这个变量只与当前线程环境有关。werkzeug中有类似的实现,使每个路由处理函数都可使用相同的request变量,而这个对象的内容只与当前请求有关。 例如:1 import threading # 创建全局ThreadLocal对象: local_school = threading.local() def process_student(): # 获取当前线程关联的student: std = local_school.student print('Hello, %s (in %s)' % (std, threading.current_thread().name)) def process_thread(name): # 绑定ThreadLocal的student: local_school.student = name process_student() t1 = threading.Thread(target= process_thread, args=('Alice',), name='Thread-A') t2 = threading.Thread(target= process_thread, args=('Bob',), name='Thread-B') t1.start() t2.start() t1.join() t2.join() 执行结果: Hello, Alice (in Thread-A) Hello, Bob (in Thread-B) 廖雪峰的官方网站 ↩︎

July 17, 2019 · 1 min · Egbert Ke

git 切换 tag

有一种源码学习的方法是这样的:从最初的版本开始看,有的很大的开源项目最初可能就只有几百行。我们可以先把项目clone到本地,然后切换到最初般。 列出所有版本: git tag 若一个tag都没有,则可能是因为你先fork了这个项目,然后本地再pull下来的,这种情况得先执行: git fetch 然后,切换到指定版本: git checkout tagname 切回到主分支: git checkout master

July 12, 2019 · 1 min · Egbert Ke