冯学荣:我们和越南同志加兄弟,为何走到互相残杀的地步?

中国和越南,同志加兄弟,当年为何会翻脸

 

冯学荣:我们和越南同志加兄弟,为何走到互相残杀的地步?
问:许多历史爱好者都说,越南人是白眼狼,中国人帮助越南人反抗侵略,给枪给钱给粮食,帮了他们那么多,到头来越南人恩将仇报。
 
答:这种说法其实就是典型的“演义”型历史叙事,就是将底层老百姓喜闻乐见的“兄弟相残”、“恩将仇报”、陈世美、杜十娘、“东郭先生和狼”之类的负心故事,简单套用到国际关系当中来,老百姓喜欢这样理解事情,因为这样理解起来最省事,但其实,这是不准确的。
 
问:国与国之间,并没有恒常的“同志加兄弟”关系,只有利益。
 
答:对的。当年以胡志明为首的越南领导集团,他们其实也是很聪明的人,他们也当然知道,中国当年援助他们抗法、抗美,并不是单纯出于所谓“兄弟情谊”,其实更多是出于国家利益的考虑。
 
问:换句话说,胡志明他们非常清楚,中国那时候援助他们,表面上是热心肠帮助越南,但其实,也是为了中国自己的国防利益。
 
答:是的。当年中国如果不援助越南,听任越南被法国或者美国或者他们的代理人控制,那么其实无异于放任中国的腰间长期被外人用一把刀子抵住,这在国防上,是一个长期的严重隐患,一旦中国和苏联或者别的国家在东面、北面、或者东北面打起来,(被外力控制的)越南在中国的后腹部捅刀子,使中国两面受敌,那是非常糟糕、非常危险的。
冯学荣:我们和越南同志加兄弟,为何走到互相残杀的地步?

青年时期的胡志明

 
问:所以当时我们要援助越南,要确保胡志明集团控制越南。
 
答:是的,胡志明毕竟和当时我们是同一个阵营的人,越南由胡志明控制,最符合当时中国的国家利益。
 
问:所以说,当年我们援助越南,表面上是出于热心肠,但实际上都是经过严密的国家利益计算。
 
答:而且我们可以反过来说,如果当年我们国家的决策者,在如此重大的国策问题上,不是从国家利益出发去考虑问题,而是从“同志情”、“兄弟义”出发去做决定,那就不是治大国,而是玩过家家。根本就没有那么草率的政治家,说白了,决策者是经过深思熟虑的。
 
问:试问我国现在援助非洲某些国家,是不是同理?
 
答:是的,同理,我们今天援助小国,出手大方,也不仅仅是出于什么热心肠,其实也是经过深思熟虑的决策,都是反复计算过国家利益的总得失,在这里大家要注意,不要被网上那些”键盘侠”、”批评癌”们带了节奏,事实上我国和其他大国一样,援助任何小国穷国,都是国际政治的通盘考虑,都是经过了国家总利益的严密计算,总之一句话,亏本的事我们是不会干的,既然干出来了,那就大概率是不亏本的。
 
问:回到越南话题。当年的越南人心里也清楚,中国援助他们,也符合中国当时的利益,所以在越南人的心里面,他们不会有过多感恩。
 
答:是。人都不笨,他也知道你帮他是有目的,只不过,大家都没有捅破这层纸,表面上天天跟你说感谢帮助,但心里都知道怎么回事。
 
问:那么,当年的越南战争,到底是怎么回事?可否简单讲讲?
 
答:我们可以用最浅显、最简单易懂的语言,把这件事捋一捋。
 
问:好。首先我们从越南的历史谈起,我们有的历史爱好者说,法国人殖民越南之前,越南是中国的一个省,这一点是否属实?
 
答:明朝以前,越南曾经多次属于中国,是分分合合的状态,越南人在自己的教科书里说“中国对越南有一千年的征服历史”,并且说“越南在历史上多次北属”,所谓“北属”就是“属于中国”的意思。不过,在公元1427年这一年,越南人黎利,率众反明,并且将明朝军队打退,进而建立了他自己的王朝,叫做“黎朝”,4年之后,明朝不想折腾了,也面对了现实、接受越南的建国,于是,公元1431年,黎朝接受明朝的册封,从那一年开始,越南成为中国的藩属国。
冯学荣:我们和越南同志加兄弟,为何走到互相残杀的地步?

黎利率众起兵抗明

 
问:也就是说,事实上从1431年开始,越南就已经不再属于中国?
 
答:是的。也有不同的算法,有人认为应该从1427年打败明军的那一年算起。值得注意的是:这是越南在古代历史上最后一次脱离中国,但事实上,在明朝以前,越南也曾有过脱离中国的记录,总之是分分合合,最后一次从明宣宗(朱瞻基)后期开始,越南就不再是中国的疆土,而是一个藩属国,这个状态,一直延续到清末的中法战争。
 
问:清末中法战争之后,越南就沦为了法国殖民地,二战期间,越南被日本占领,日本投降之后,法国人又回来了。法国人为什么回来?
 
答:二战之后的法国人认为,法国和越南在历史上签署的殖民地条约,都是“有效”的,只不过是在二战期间被德国、日本等国家打断了,属于“不可抗力”,现在恢复了常态,条约应该继续履行,所以,法国人坚持认为,他们在越南的殖民统治,是“理应恢复”的,所以二战之后,法国人决定“重返越南”,试图延续在越南的殖民统治。
 
问:可是今时不同往日,二战之后的越南有胡志明,他们不再甘心当亡国奴,他们拿起武器,抵抗法国人,为越南的独立而战。
 
答:是的。这个时候的越南,已经不是二战之前的越南了,这个时候,胡志明领导越南子弟,对法国人奋起反抗,而且,这次胡志明并不是孤军作战,而是有一个大哥哥、一个大姐姐在背后撑腰的,“大哥哥”是中国,“大姐姐”是苏联。
 
问:据说中国还派了许多军事顾问去越南助战?
 
答:是的。陈赓就是一个代表。而且还不仅仅是“顾问”那么简单,而是直接参与了战役的指挥。我们知道1954年春夏之交,越南人和法国人打了一场“奠边府战役”,在这场战役里,越南人打败了法国人,但其实这场战役,就是陈赓、韦国清和武元甲共同指挥的,其中,陈赓和韦国清,都是中国派过去的高级将领。
冯学荣:我们和越南同志加兄弟,为何走到互相残杀的地步?

我国大将陈赓(右三)和胡志明(右四)

及其他越军将领在越南共同指挥作战

 
问:越南人拍的故事片电影《奠边府》,全剧都不见陈赓的影子。
 
答:是。越南人一直在文化和历史等方面“去中国化”,所以,越南人拍摄的历史题材的电影,都会有意地隐去中国援助方的角色。
 
问:法国人和越南人打仗的时候,美国人给法国人输送了源源不断的军事援助,这是为什么?这件事跟美国有什么干系?
 
答:事情是这样的,当年法国人说,我们要“重返越南”、“恢复法兰西的荣光”,法国人是为恢复殖民地而战,美国人则说,我的法国朋友,你在打胡志明,我来帮你,你缺枪、缺炮、缺钱什么的,我们美国人给你。法国人不解,问美国人:你为什么帮我?我打胡志明,和你有什么关系?我是在为维护殖民地而战,你们美国人不是一向反对殖民统治吗?美国人则说,我才不是为了帮你恢复殖民地,我是为了遏制苏联在东南亚的扩张。
 
问:这件事很有趣,当年胡志明的抗法事业,是具有双重性质的事业,一方面,是民族主义性质,要为越南独立而战,另一方面,是为了复制苏联体制而战,具有苏联意识形态扩张的性质。
 
答:是。当年就是这么有趣。法国人打胡志明,是为了维护殖民统治,美国人不赞同法国的殖民主义,但由于胡志明是苏联的代理人,胡志明控制越南,等同于苏联控制越南,美国人不乐见,所以美国人对法国人实施军事援助。
 
问:法国人接受了?
 
答:法国人接受了美国人的援助。法国人说,我管你是否支持我恢复殖民地,总之,我和胡志明打仗,你援助我,我就要,你只管给,我就只管拿。不拿白不拿。
 
问:于是我们看历史,发现一个很有趣的现象,法国人打胡志明,美国人援助法国人,但是,同一场战争,法国人和美国人虽然在同一个战壕里,但是,他们的战争目的,其实不一样。
 
答:对的,历史就是这样有趣。但是以胡志明为首的越南人不这样想。从越南人的角度看来,美国人和法国人一样,都是要阻止越南人独立的恶棍。越南人分不清楚法国人和美国人的战略目的有所不同。当时以胡志明为首的越南人,既恨法国人,也恨美国人。他们对越南平民的宣传是:法国人、美国人,都是侵略者,都是要奴役越南人民的,所以,不想当亡国奴的,你就跟我起来反抗。
 
冯学荣:我们和越南同志加兄弟,为何走到互相残杀的地步?
问:当时中国人援助越南人,不但派出高级将领直接指挥,而且还给越南送去粮食、武器、弹药、各种后勤补给。
 
答:对的。甚至高炮部队,都是中国派过去的,换一身越南人民军的服装,其实是中国兵,而且,有伤亡,所以,中国人帮助越南人打赢法国人,功劳非常大,当时说是“鲜血凝固成的友谊”,是一点都不夸张的。可以说,没有中国人的帮助,胡志明是打不赢法国人的。所以在当时,最起码奠边府战役前后,越南人是非常感激中国人的。
冯学荣:我们和越南同志加兄弟,为何走到互相残杀的地步?

奠边府战役,法国人向越南人投降

 
问:最初越南人对中国人是感恩的。后来为什么,恩情变成了仇恨?
 
答:关键就在于一件事:日内瓦会议。这件事,是一个重要的分水岭。1954年夏天,中、苏、美、法、英等国家,在瑞士日内瓦,开了一场会议,讨论越南问题。法国人在奠边府战役中战败,也不想再打了,于是,寻求和平撤出。
 
问:这次日内瓦会议的最主要的成果是什么?
 
答:最主要的,就是各方同意,以北纬17度线为界,将越南分为两半,北越实行社会主义,南越实行资本主义。
 
问:中国也是与会方之一,中国为什么会同意这个?为什么中国不支持胡志明继续打下去、统一越南?
 
答:中国是有苦衷的,中国的第一个苦衷就是,其实打完奠边府战役之后,中国没有办法支持胡志明往南打了,因为中国当时既没有制空权,也没有制海权,由北往南打下去,战线太长,法国人在美国人的帮助下,很容易把越南人民军拦腰截断,因此从军事上,不能再打了。中国的第二个苦衷是,当时是1954年,朝鲜战争打完才一年,当时中国在国际上,处处受包围,因此,中国想借助日内瓦会议的机会,释放一个友好的姿态,以换取国际关系的缓和,具体来讲,是想打破一些封锁和一些禁运,并且扩大国际上的经贸往来,等等这些。
 
冯学荣:我们和越南同志加兄弟,为何走到互相残杀的地步?
问:也就是说,中国在日内瓦会议上,客观上,主观上,都有困难。
 
答:是的。
 
问:那么,以北纬17度线为界,将越南一分为二,胡志明是否同意?
 
答:胡志明当然不同意,但是,中国的代表,找了胡志明,做他的思想工作,跟他做了详细的解释,后来,胡志明也就勉强接受了。
 
问:胡志明为什么不同意呢?
 
答:因为胡志明认为,当时中国作为越南的大哥,不应该半途妥协,而应该一鼓作气、继续帮助越南由北向南以迅雷不及掩耳之势打到西贡去,统一全越南。不过既然中国人坚持己见,胡志明也就作罢。
 
问:那么胡志明的幕僚呢,他们是否同意?
 
答:意见很大。大家谈起这件事,都拍桌子骂娘。你比如说武元甲、范文同、黎笋、文进勇之类的这些越南大员,都是非常不满的,对中国的意见很大,都说中国在日内瓦会议上,是“出卖”了越南。
冯学荣:我们和越南同志加兄弟,为何走到互相残杀的地步?

日内瓦会议,

以北纬17度线为界把越南分为两半,

越南人恨中国主要是因为此事

 
问:可是胡志明直至他1969年逝世,他和中国的关系仍然保持良好,这又是为什么?
 
答:两个原因。第一,法国人战败滚蛋之后,美国人说法国人真脓包,无奈之下,决定亲自动手,杀了进来,以“遏制苏联主义在亚洲的扩张”,这,就是美国和越南之间的“越南战争”爆发的缘由。为了继续争取中国的援助,胡志明暂时把所有的不满,都深埋于心底,所以他表面上,仍然保持对中国友好,所以直到他死,他都没有和中国翻脸。第二、胡志明在越南所有的领导人里面,算是修养最好的一个,而且本身又和中国革命先辈保持着很深厚的个人友谊,所以,北纬17度线导致越南分两半这件事,胡志明表面上表示理解和接受。
 
问:但是胡志明一死,事情就发生变化了。
 
答:对的,1969年胡志明病逝,他的部下武元甲、范文同、黎笋、文进勇这些人,开始接管越南,但是,直至1975年越南人赶走美国人之前,这个时候,越南仍然需要中国的帮助,所以暂时来讲,也没有和中国翻脸。一旦赶走了美国人之后,事情就迅速发生了变化。尤其黎笋这个人,胡志明死后,黎笋实际掌权,黎笋对中国不懂感恩,他恨中国,他认为中国“曾经阻挡越南统一”、“不是真正的朋友”,而是“潜在的敌人”。不但如此,黎笋此人心胸十分狭窄,举个例子:1972年中国为了抗衡苏联,和美国开展乒乓外交,那一年美国和越南还在打仗,有一回美国对北越的轰炸加重了,黎笋竟然恶意猜测是中国人叫美国人加重对北越的轰炸。这是黎笋在越南国内讲话透露出来的看法,被记录进了史料里,其实根本就是无稽之谈,中国根本没有叫美国加重轰炸越南的动机和利益。
 

冯学荣:我们和越南同志加兄弟,为何走到互相残杀的地步?

胡志明去世之后越南的实际领导人黎笋
此人心胸狭窄,中越当年交恶,此人有重大责任
 
问:这里还有一个重大事件,从1972年开始,中国和美国开始洽谈建交的问题。
 
答:对的,这件事对越南人刺激也很大,从越南人的眼中看来,他们认为中国大哥再一次“出卖”了他们。越南人说,中国人在日内瓦会议“出卖”了越南一次,中美关系正常化,又“出卖”一次。他们说,当年奠边府战役我们打赢了,本来可以顺势南下,一举解放全越南,当时是中国人按住我们,阻止我们统一越南,看,这次中国人又和美国人眉来眼去了,还说要建交了,这样的“大哥”,真是“靠不住”。
 
冯学荣:我们和越南同志加兄弟,为何走到互相残杀的地步?
问:越南人觉得很受伤。
 
答:对。武元甲、范文同、黎笋、文进勇他们那些人,当时就是这样想的。可是,尽管他们内心深处恨中国,可是表面上仍没有闹翻,而是频繁跑到北京来,要钱,要枪,要物资,狮子大开口。他们是什么心态呢?两个心态,第一个心态,因为习惯了中国的援助,因为你一直都给我,那么你给我就是应该的,第二个心态,他们认为中国在日内瓦会议、中美关系等各方面,对越南有所亏欠,所以他们狮子大开口,“理直气壮”,一点都不客气。
 
问:这正是中国古训“升米恩,斗米仇”的一个典型事例。
 
答:正是。中国人帮助越南人打赢奠边府战役,可是越南人觉得不够,他们要中国人继续帮助他们统一越南,中国人说做不到,有困难,于是越南人就记恨中国人了,就像你帮助一个亲戚,借给他十万元,他日后说,上次你借给我十万,其实还不够,这次我要你借我一百万。你借不借?不借,你就是坏人。
问:1976年之后,中国对越南的援助开始减少,那是为什么?
 
答:三个原因。第一个原因,老一辈和胡志明有交情的革命家,去世了,人亡必然政息,或多或少,这是必然的,第二个原因,中国认为美国人都打跑了,你越南应该自力更生,不要总是来北京找我要这要那,而且当时中国百废待兴,经济也是非常的困难,所以1976年之后,中国对越南的援助,确实是逐步减少了。第三个原因,当时中国对越南说,我们继续援助你们越南,但是要求你们越南拒绝苏联的援助,向我中国一边倒,你愿意吗?越南人说:我不愿意,我中、苏两家都要吃。中国一看这小弟靠不住,于是就减少援助了。
 
问:再后来,越南就一边倒,倒向了苏联。
冯学荣:我们和越南同志加兄弟,为何走到互相残杀的地步?

越南开国元勋武元甲和他的越军官兵

 
答:很大程度上是这样。
 
问:越南人会不会说,既然你中国不援助我,那么我只能倒向苏联,除此之外,我别无选择。
 
答:他们当年就是这样认为的,他认为除此之外无路可走。而且他们觉得,中国这个“大哥变了”,以前不但在日内瓦会议“背叛”了我越南小弟,而且现在你也不再援助我了,忍心看着我穷、忍心看着我挨饿,你也不管了,真是狠心啊,这样一想,仇恨就更深了。本来中国就不欠越南的,当年帮助他打败法国人,他得寸进尺,认为你应该继续帮助他统一越南,你不帮,他就怨恨你,后来打美国也一样,中国给越南送钱、送枪、送粮食、送物资,打完美国人,后来就不送了,于是越南人觉得“大哥变了”,认为“感情受到了伤害”,由感恩变成了仇恨,真是古语说得好,升米恩,斗米仇,你给穷人一升米,够他一家吃饱一顿饭,穷人非常感激你,但是如果你给穷人一斗米,够他全家吃一个礼拜,这样就惯坏他了,以后他就认为你帮助他是应该的,所以你必须继续帮下去,哪天你不帮了,于是对方就马上怨恨你,这就是所谓的“升米恩,斗米仇”,古人真是总结得好。
 
问:那么后来越南侵略柬埔寨,宣称要建立“印度支那联邦”,这又是怎么回事呢?
 
答:其实在历史上,越南人一直都在碾压柬埔寨,越南今天有许多领土,就是在历史上侵占柬埔寨的。1975年的越南,为什么要打柬埔寨呢?越南官方的说法,是因为柬埔寨红色高棉屠杀越侨。红色高棉那时有没有屠杀越侨呢?有。但,越南攻击柬埔寨,有更深层次的动机,当时越南人总结:越南被法国、日本、法国、美国等大国,反复殴打,反复碾压,他们认为越南之所以受欺负,就是因为国家太弱小,所以越南想整合曾经的“法属印度支那”,也就是越南、柬埔寨、老挝三个国家,建立一个由越南人统治的“印度支那联邦”,这样,越南就成为一个超级大国,以后子孙万代,就再也不用受外人欺负了。
冯学荣:我们和越南同志加兄弟,为何走到互相残杀的地步?

昔日法属印度支那疆域图,

黄色为越南,红色是柬埔寨,

绿色是老挝,越南想整合这三块,

把越南打造成一个超级大国

 
问:但是越南人没有想到的是,我们中国显然不会乐见在国家的西南边,又出现一个超级大国。
 
答:是的。中国当时北边有苏联,西边有印度,东边面对日本这个潜在的重新崛起的大国,南中国海呢,还要防范美国的战略包围……各种压力,已经喘不过气来,这个时候如果在南疆再出现一个名叫“印度支那联邦”的超级大国,而且还是苏联的帮凶,那对中国来说,就很麻烦了。所以中国就要教训越南,要赶在“印度支那联邦”成型之前,提前把它打掉,这就是中越后来开战的主要原因之一,不过当然了,这不是那次交手的唯一原因,还有其他的原因,篇幅缘故,留到下次再详细谈。
 

转自:https://mp.weixin.qq.com/s/GDmKo520ZAtgbk-byp4uXA

如果没有中俄联手,那么世界早已是美国的了!

来源:天涯时事(本文不代表金融纵横谈立场)

 

昨天的文章有人提出一个非常好的问题:北约东扩就能“围死”俄罗斯吗?

后来,我发现,不仅仅是他,还有很多人想不通北约东扩的目的,他们的疑问是:就算俄罗斯周边所有的国家都加入了北约,又能怎么样?难道北约敢和俄罗斯开战?既然不敢开战,那么怎么能围死俄罗斯?

今天,我们将给大家解答这个问题。

想要了解这个问题,我们必须要了解俄罗斯的工业布局。

俄罗斯的国土分为两部分——以乌拉尔山脉为分界,乌拉尔山以东属于亚洲部分,就做西伯利亚;乌拉尔山以西属于欧洲部分,叫做东欧平原。

如果没有中俄联手,那么世界早已是美国的了!

俄罗斯主要有四个工业区,主要分布在乌拉尔山以西的东欧平原:

第一,圣彼得堡工业区。

这个工业区的石油化工、造船、电子、造纸和航空航天等工业十分发达,也是俄罗斯食品和纺织工业最发达的地区。

第二,莫斯科工业区。

这个工业区是俄罗斯工业最发达的地区,主要有钢铁、汽车、飞机、火箭和电子等工业部门。

第三,乌拉尔工业区。

这个工业区主要生产石油、钢铁、机械等。

第四,新西伯利亚工业区。

这个工业区主要生产煤炭、石油、天然气、电力、钢铁等。

如果没有中俄联手,那么世界早已是美国的了!

为什么要这么分布?

很显然,就是气候的原因:乌拉尔山以西的东欧平原气候相对比较温暖,而且靠近欧洲,是人口聚集区;乌拉尔山以东的西伯利亚气候极其寒冷,发展工业代价比较大,仅有一些能源企业分布在这个地区。

这样的工业布局注定了俄罗斯的贸易只能依靠欧洲,不能依靠中国。

为什么这么说?

因为俄罗斯和中国之间只有一条路程极其遥远,且效率极其低下的西伯利亚大铁路——这条铁路全长8000多公里,设计时速只有80公里。

如果没有中俄联手,那么世界早已是美国的了!

铁路的运输成本是比较高的,平均每吨、每公里的价格大概为0.1元。

8000公里的路程,仅仅运输费用就需要800元,这不是一般商品能够承担的。

比如,煤炭的价格在600-1000元/吨左右,铁矿石的价格在700-1200元/吨之间,如果从俄罗斯进口煤炭和铁矿石等,那么根本不划算,这就是为什么俄罗斯的煤炭和铁矿石也很丰富,但是中国却从巴西、澳大利亚等国进口而不从俄罗斯进口的主要原因——巴西和澳大利亚的铁矿都在沿海地区,生产出来可以通过海运直接运输到中国,运输成本比较低,平均每吨只需12美元左右,也就是80元左右。

事实上,俄罗斯的石油运输到中国的成本也比较高,但是由于石油关系到国家能源安全,所以中俄之间不得不花大代价建设石油管线。

如果没有中俄联手,那么世界早已是美国的了!

过去的十几年,欧美不断的制裁俄罗斯,俄罗斯经济比较困难,不得不加大和中国的贸易,但是也仅仅局限于向中国出口一些大豆、木材等,而这些大豆和木材也不是从东欧运输过来的,而是在靠近中俄边境的区域,数量比较有限。

主要原因有两点:

第一,俄罗斯面积虽大,但是适合种植的区域极其有限;

俄罗斯是世界上面积最大的国家,但是它有65%的领土是永久冻土,根本无法种植,只在靠近黑龙江的远东地区有一些种植潜力。

第二,气候寒冷,不适合生存,人口不足;

由于俄罗斯在中国的北方,气候比黑龙江还要寒冷,所以俄罗斯大量人口都迁移到东欧平原了,远东地区人口稀少,没有足够的劳动力开发农业。

所以,中俄之间的贸易,除了石油和少量农产品外,主要是以附加值比较高的商品为主,否则无法承担高昂的运输费用。

了解这个问题以后,你就会知道北约动扩的第一个要害:北约东扩以后,必要时,美国可以指使俄罗斯周边的国家对俄罗斯实施经济制裁,断绝俄罗斯与欧洲之间的贸易联系。

当俄罗斯周边的国家对俄罗斯实施经济制裁的时候,那么俄罗斯大量的石油和天然气、煤炭、铁矿等就无法通过陆地运输到西欧国家,这样既能打击俄罗斯的经济,同时可以要挟欧盟。

如果没有中俄联手,那么世界早已是美国的了!

我们以石油和天然气为例。

下面这个图就是俄罗斯向欧洲的输气管道分布图,其中有三个关键国家,乌克兰、白俄罗斯和波兰。

如果没有中俄联手,那么世界早已是美国的了!

前些年,乌克兰在美国的怂恿下和俄罗斯发生矛盾,俄罗斯切断向欧洲国家供气,使欧洲保加利亚、斯洛伐克、捷克等多个国家受到影响。

如果没有中俄联手,那么世界早已是美国的了!

波兰也是非常反俄罗斯的,只要美国一声令下,那么波兰就可以断了俄罗斯向德国的输气管线,那时德国就不得不高价向美国购买天然气。

当然了,如果美国能让白俄罗斯也加入北约,那更保险:如果波兰在德国的压力下不敢断了通向德国的输气管线,那么美国还可以要求白俄罗斯断了俄罗斯输向欧洲的输气管线。

正是因为北约已经东扩到俄罗斯的家门口了,陆地被封锁的死死的,所以俄罗斯非常被动,不得不想尽办法的避开陆地,于是就有了北溪1号,北溪2号和南溪管道。

为了避开波兰的制衡,俄罗斯和德国通过波罗的海建设了北溪1号输气管线,但是由于输气量不足,又建立了北溪2号。

如果没有中俄联手,那么世界早已是美国的了!

这几年,美国不断的抨击德国,甚至不惜制裁参加北溪2号管线建设的欧洲企业,其目的就是为了中断俄罗斯的天然气出口。

如果没有中俄联手,那么世界早已是美国的了!

同样的道理,俄罗斯为了避开乌克兰,不得不设计了南溪管线,将天然气出售给巴尔干国家。

如果没有中俄联手,那么世界早已是美国的了!

但是,这样就有用了吗?

没有用啊,因为保加利亚也加入了北约了。

只要保加利亚断了俄罗斯管线,俄罗斯的天然气依旧卖不出去。

现在大家知道北约东扩的第一个意义了吧。

北约是被美国控制的,如果俄罗斯周边的国家都加入北约了,那么美国就可以利用经济手段打压俄罗斯,同时对欧盟的实际老大德国进行制衡,逼迫其以高价购买自己的石油和天然气。

如果没有中俄联手,那么世界早已是美国的了!

北约东扩以后,俄罗斯的陆地出口全部被美国控制,怎么办?

所以,俄罗斯还需要发展海洋运输

大家看看下面的图,这个图就是10万吨油轮的运输路线:俄罗斯的石油主要依靠圣彼得堡和新罗西斯克港口运输出去。

如果没有中俄联手,那么世界早已是美国的了!

但是,新罗西斯克港口的石油必须要经过土耳其海峡,圣彼得堡港口的石油必须经过斯卡格拉克海峡,而土耳其海峡控制在土耳其手中,斯卡格拉克海峡控制在丹麦手中——土耳其和丹麦也都是北约成员国。

在和平时期,商船是可以自由通过各个海峡的,但是在战争时期就可能不会让你的商船通过了。

2015年的时候,叙利亚战争正进入关键阶段,俄罗斯的战机不断的轰炸叙利亚境内的反政府武装,而叙利亚反政府武装就是土耳其支持的。于是,埃尔多安下令击落俄罗斯的战机——这就是震惊世界的“11.24俄罗斯战机被击落事件”

如果没有中俄联手,那么世界早已是美国的了!

这件事把美国和德国吓的半死,因为这很可能导致一场世界大战——由于土耳其是北约成员国,按照北大西洋公约组织条例,如果其它国家对成员国发动战争,那么将被视为对整个北约发动战争,北约必须反击。

埃尔多安为什么敢击落俄罗斯战机?

除了有北约在背后撑腰外,就是因为土耳其拥有土耳其海峡——如果俄罗斯对土耳其发动攻击,那么土耳其一定会关闭土耳其海峡,那时俄罗斯的商船一艘都别想从土耳其海峡出去。

埃尔多安胆大包天,为了防止这个“极端分子”再次冒险挑衅俄罗斯,美国和欧盟在2016年策划了土耳其军事政变——埃尔多安差点被炸死,专机飞往德国,但是德国却拒绝其降落,最终不得不冒险回国。

这就是“7·15土耳其军事政变事件”

如果没有中俄联手,那么世界早已是美国的了!

俄罗斯被土耳其击落两架战机,普京都忍了,为什么啊?

我认为,其中的一个最重要原因就是:土耳其控制着土耳其海峡。

所以,北约东扩以后的一个重要作用就是:美国随便用一个借口就能切断俄罗斯与欧洲大国的陆地联系,然后再挑起土耳其、丹麦与俄罗斯的矛盾,切断俄罗斯的海上路线,全面封锁俄罗斯的经济。

那时,俄罗斯的石油、天然气、铁矿等资源和能源卖不出去,外部的商品也进不来(俄罗斯轻工业比较薄弱,几乎完全依靠进口),经济必然会一落千丈,民不聊生。

没有了卖资源和能源的钱,俄罗斯拿什么来支撑自己庞大的军事开支?

 

北约东扩除了从陆地和海上全面封锁俄罗斯外,还有一个目的:必要时,可以把俄罗斯拖进战争的泥潭中,不断消耗它的实力,直至流干它最后一滴血。

二战后,美国发动了朝鲜战争、越南战争,最终都失败了。

苏联入侵了阿富汗,也失败了!

为什么会失败?

主要有两个原因:

第一,这些国家都是山地国家,易守难攻;

第二,这些国家的背后都有大国支持。

像伊拉克、利比亚那种平原或沙漠国家,对于美国来说,很好打,因为你根本就无处躲藏——无论是人员,还是武器和物资都很难掩藏,很容易被炸掉。

但是,山地国家就不一样了,你可以把人员、武器和物资等,隐藏到山区里面打持久战——仅仅依靠轰炸是没有用的,必须要出动规模庞大的地面部队。

但是,仅仅依靠山地地形就能获胜了吗?

以美国的军事实力,即使你是山地地形,你生产武器和物资的工厂是肯定能给你摧毁的。

没有武器制造厂,你能坚持多久?

所以,山地国家想要打败超级大国还必须要有其它国家给它源源不断的提供武器和物资。

比如,朝鲜战争的时候,不仅仅中国亲自参战了,而且苏联也提供了大量的武器装备和物资;越南战争的时候,中国给北越提供无法计算的武器和物资;阿富汗战争的时候,中国、巴基斯坦和美国给阿富汗提供大量的武器和物资……

正是因为这个原因,大国和大国之间必须要有“战略缓冲区”。

什么叫做“战略缓冲区”?

就是指:大国周边的小国不得“站队”,作为与其它大国之间的缓冲区——你可以不做我的小弟,但是你绝对不能认其它人做大哥——否则,灾难必然来临。

中国为什么要参加抗美援朝?

如果朝鲜被美国占领了,那么美国就可以把枪口直接顶在中国脑门上了——随便找个借口就让朝鲜和中国打起来,那时美国在背后给朝鲜提供资金、武器和各种物资,那样就能把中国拖进战争的泥潭之中——就像美国陷入越南战争的泥潭和阿富汗战争的泥潭中一样。

北约东扩以后,美国就可以通过这种方式把俄罗斯拖进战争的泥潭中,从而不断消耗俄罗斯的经济和军事实力,直至它承受不了为止。

所以,大国和大国之间一定要有战略缓冲区。

苏联为什么要外蒙古独立啊?

就是想用外蒙古把中国和苏联隔开,在中苏之间建立一个战略缓冲区,防止中苏起直接冲突。

关于这点,蒋经国在对1945年夏随宋子文赴苏联谈判签订《中苏友好同盟条约》的回忆中说道:

我也就开门见山地问他(斯大林)说:“你为什么一定要坚持外蒙古‘独立’?外蒙古地方虽大,但人口很少,交通不便,也没有什么出产。”

他干脆地说:“老实告诉你,我之所以要外蒙古,完全是站在军事的战略观点而要这块地方的。”

他并把地图拿出来,指着说:“倘使有一个军事力量,从外蒙古向苏联进攻,西伯利亚铁路一被切断,俄国就完了。”

如果没有中俄联手,那么世界早已是美国的了!

也正是因为这个原因,在苏联解体之前,戈尔巴乔夫对美国提出一个要求:美国永远不能让北约东扩。

2001年的时候,戈尔巴乔夫在自己的新书中透露,早在1989年他就从西方得到北约不东扩的保证,波罗的海3国不应被吸收加入北约。

他在书中说:根据他同西方达成的协议,1989年民主德国与联邦德国实行统一的条件之一是北约不东扩,但后来西方违反了这一国际协议。

2009年的时候,戈尔巴乔夫78岁,在北约贺寿的时候,他接受了德国之声的采访,他又痛苦地回忆了自己被北约欺骗的经过。

戈尔巴乔夫说,德国、美国和其他西方国家在1990年德国统一后对他承诺,北约一厘米也不会向东推进。但是美国人没有履行承诺,德国人也在这个问题上表现出无所谓的态度。“甚至有可能,他们正在为能够把俄罗斯人赶跑而高兴呢。但是,这却‘让俄罗斯失去对西方承诺的信任’。”

如果没有中俄联手,那么世界早已是美国的了!

现在大家知道北约为什么要东扩了吧,也知道为什么俄罗斯对北约东扩那么敏感了吧。

主要就是两点:

第一,北约东扩后,它随时可以切断俄罗斯对外的经济联系;

第二,北约东扩后,它随时可以威胁俄罗斯的国家安全形势。

这些年,北约不断东扩,不断的想把俄罗斯拖进战争的泥潭(车臣战争、格鲁吉亚战争和乌克兰战争),俄罗斯的形势非常危险,稍有不慎就可能“万劫不复”。

正是因为这个原因,俄罗斯才和中国结成全面战略协作关系。

2020年1月的时候,中国外交部对外发表一则声明:“……中俄全面战略协作伙伴关系迈入新时代,日益地成熟、稳定、坚韧,不受国际风云变幻和双方各自国内政治进程的影响……

如果没有中俄联手,那么世界早已是美国的了!

如果你对国际政治关系有比较深的理解,那么就会知道这句话意味着什么?

“不受各自国内政治进程影响”的意思就是:无论俄罗斯国内谁当总统,无论俄罗斯国内发生什么状况,任何人都无法改变俄罗斯与中国之间的关系。

除了俄罗斯,全世界,只有中国和巴基斯坦有这种关系——巴基斯坦国内也有很多政治派系,包括反政府势力,但是没有任何一个派系敢改变中巴关系。

其实,这也是明确的告诉世界:中俄、中巴关系不受挑拨、不受离间,没有任何人、任何事能改变中俄、中巴之间的关系,双方永远支持对方的核心利益。

也正是因为欧美不断的压缩俄罗斯的生存空间,这才让中俄能紧密的联系到一起。

正是因为中俄坚定的联合在一起,这才让俄罗斯在欧美的不断围堵下能坚持不倒;正是因为中俄坚定的联合在一起,这才让我们承受的压力得到分担;正是因为中俄坚定的联合在一起,这才没让美国能控制全世界,反而陷入被动之中……

没有中俄联手,世界恐怕早就是美国的世界了!

—–全文到此为止。

转自:https://mp.weixin.qq.com/s/HDX1SenA6qRwuUTG35SF8Q

估值50亿的网红美妆店,卖我一堆假小样?

 

买正品前先买小样试用,早就成了新的消费正义。

者:水何
来源:Vista氢商业(ID:Qingshangye666)

作为一个北漂姑娘,我就住在团结湖的老居民楼里。房子位于三里屯附近,优点是交通方便、外卖好吃,缺点是这里连一粒尘土都飘扬着金钱的气味。

 

比如说,这已经是我第221次通勤时路过这座全玻璃覆盖的长方形建筑了:

 

估值50亿的网红美妆店,卖我一堆假小样?

 

每当夜幕降临后,这家店就向我散发出富丽堂皇、奢华典雅以及,穷人勿近的凡尔赛气息。

 

估值50亿的网红美妆店,卖我一堆假小样?

 

店门口,总有不少精致女孩大排长龙,每次路过时,我都会远远地望上一眼,然后灰溜溜地低着头快步走开。

 

直到有一天,我听编辑部说这家店是话梅,一家主打售卖小样的美妆店。就这?就这?我瞬间就升起了探店的欲望,计划挑个好日子直冲这座我心目中的宫殿。

 

01
估值50亿的美妆店难道售卖“假货”?

 

2月28日,北京雨夹雪,我满心欢喜地盘算着这鬼天气谁还会出门,却没想到话梅门店里头依然人头攒动、比肩接踵。

 

估值50亿的网红美妆店,卖我一堆假小样?

我想象中的门店内部

 

估值50亿的网红美妆店,卖我一堆假小样?

实际上有多少人,示意图

 

对于没有购物目标的人来说,我一时不知从哪逛起。于是我观察了一阵,发现有一类人,她们一跨进店门就大步流星地冲向了二楼。

 

跟随着她们的步伐,果然没我失望。

 

来到二楼,这里,整齐陈列着北京最全的护肤品——

 

估值50亿的网红美妆店,卖我一堆假小样?

估值50亿的网红美妆店,卖我一堆假小样?

 

这里,还有各种节日限定款、各种品牌的合作联名款刺激着女孩的多巴胺直线飙升——

 

估值50亿的网红美妆店,卖我一堆假小样?

 

但当我随手拿起一瓶常用的澳尔滨健康水看了看标价时,奇怪的事情发生了:我用手指算了算差价,发现一瓶330ml的正装,话梅还比品牌店38节活动价要贵上30块钱。

 

估值50亿的网红美妆店,卖我一堆假小样?

 

再比对了几款我常用的护肤品、香水价格后,我满脑子都是问号:

 

在如今商场、专柜和品牌线上店打折早就成了常态的前提下,这儿售卖的正装护肤品在价格上丝毫没有任何优势啊??

 

估值50亿的网红美妆店,卖我一堆假小样?

 

但当我激动地把我的结论发到编辑部,却没想到又孤陋寡闻了,橘总表示谁搁这买正品呢?大家伙抢购的都是小样。

 

于是我来到人像下锅的饺子一样多的底层,玲琅满目的小样摆放得像村口阿婆卖小白菜,给你一种“不买就是吃了大亏”的冲击感。

 

估值50亿的网红美妆店,卖我一堆假小样?

 

这些写着非卖品的各品牌小样,看着就跟在义乌搞批发似的。正当我摩拳擦掌准备抢购一番时,一看标签价格却惊呼是天菜!

 

估值50亿的网红美妆店,卖我一堆假小样?

 

一两百的标价让我的购物欲瞬间熄灭,一个冷峻的问题摆在我的面前:

 

这小样平时都是白送我的,原来那么值钱呢?

 

估值50亿的网红美妆店,卖我一堆假小样?

 

但本着“来都来了”的优秀传统,我还是挑挑拣拣了一箩筐的小样,美滋滋地结了帐。

 

回家路上我本能地打开多个社交网站,想搜搜这家店的风评咋样,没想到却看到了不少美眉对产品及货源的评论和质疑。

 

估值50亿的网红美妆店,卖我一堆假小样?

估值50亿的网红美妆店,卖我一堆假小样?

 

脑门突然凉飕飕,一股大事不妙的预感涌上心头。

 

一到家我就拿出专柜送的小样进行了对比,发现包装上的字号和字体是有点细微差别。

 

估值50亿的网红美妆店,卖我一堆假小样?

 

但要想真的整明白这小样真不真,还是得去专业机构,找正规的、懂行的鉴定专家瞅瞅。

 

可为了个百来块的小样,谁也不想花啥大价钱做检测,于是我打开了万能的闲鱼,寄希望于寻求懂行的姐妹帮忙看上一看。

 

马上一位好评1w+的“鉴定大师”就入了我的法眼——

 

估值50亿的网红美妆店,卖我一堆假小样?

 

在交了1块2毛8的检测费后,我遵循着“鉴定大师”的简易指引,等待着最后的审判。

 

而大师人狠话不多,草草地审阅完几张聚焦不太成功的产品图后,“啪”一下很快啊!秒回我。

 

估值50亿的网红美妆店,卖我一堆假小样?

 

虽然我还在疑惑这一块钱的“鉴定大师”到底可不可信,但还是怒从心头起,马上去话梅线上找客服battle,客服小哥则礼貌客气地跟我玩起了踢皮球。

 

估值50亿的网红美妆店,卖我一堆假小样?

 

一想到去线下门店维权,对方肯定要求我出具官方的检测报告,我只好咬碎口中牙,气得像圆鼓鼓的小猪奶黄包被人戳中了脑袋。

 

虽然我无法言之凿凿地判定话梅这家美妆店是售假,但红星新闻的记者曾就货品来源向欧莱雅(中国)、爱茉莉太平洋集团和资生堂集团求证,对方皆表示其未对话梅进行授权。

 

估值50亿的网红美妆店,卖我一堆假小样?

 

而就是这么一家网红美妆店,却做得风生水起,赚得盆满钵满。

 

根据蓝莓财经的报道,话梅的第一家门店位于上海安福路,仅仅花了4个月就实现了收支平衡,而传统的线下化妆品实体店则一般需要12个月。

 

估值50亿的网红美妆店,卖我一堆假小样?

 

到了2020年9月,随着钟鼎、黑蚁等资本机构的加入,话梅的估值成功超过了50亿元。

 

估值50亿的网红美妆店,卖我一堆假小样?

 

上述种种乱象的背后,不光话梅成功了,小样市场也崛起了。

 

02
小样,成了收割女孩的重灾区

 

正所谓有需求就会有供给,有贪念就会有割韭菜。小样市场的迭代有几个重要的变化,但假货横行却一直为人所诟病。

 

在最一开始,女孩们会选择在淘宝上购置小样,一看到“粉丝数十万量级、多个商品月销数千、三皇冠、100%好评”的店铺,就确信是正品无疑。

 

而不少保持着高评分的十年老店,还往往以2-5折的优惠价格在售卖明星产品的小样,更是会让人迈不开脚,火速下单。

 

估值50亿的网红美妆店,卖我一堆假小样?

▲有多少女孩以为小样就值几十块呢?举手我看看

 

我们现在大可轻松调侃这些价格低廉的小样99%多是山寨货,但多数人,是真的分不清到手的山寨货和正品有什么区别。

 

于是打开小红书,上千帖子都是《烦请大神帮我鉴定小样真假》。

 

估值50亿的网红美妆店,卖我一堆假小样?

 

年少无知时,我也上过这个当。

 

但随着央视不断地暗访和曝光后,越来越多的女孩醒悟了,敢情自己手中一两百的产品都来自于中山、东莞的小日化厂,成本只要二三十块。与其被无良的投机商家骗钱,女孩宁愿咬咬牙去专柜买正品。

 

估值50亿的网红美妆店,卖我一堆假小样?

 

不过,苦日子没过几年,女孩们的春天很快就来了。

 

“菌菇水买200ml送200ml,某黑绷带买50ml送6个5ml小样,某面膜买50ml正装送两个30ml小样……”

 

凡是在李佳琦、薇娅等带货主播的直播间买过东西的女孩都明白,比正品还多的赠品小样就是她们每晚坚守在手机前的原因。

 

去年双十一直播间强势的优惠力度,更是让女孩们血战到了天明。

 

估值50亿的网红美妆店,卖我一堆假小样?

 

这时,小样的属性发生了改变,不仅是一种捡漏秘诀,还成了很多人的致富密码。

 

“李佳琦直播拼单,已收到货品,转卖部分小样,提供开箱视频,有需要抓紧私聊。”去年,双11购买的商品刚入手,就有不少人在闲鱼上发出了转卖的帖子。

 

据咸鱼平台的了解,在去年双11过后的第二天,闲鱼平台上美妆闲置小样的发布数量就比前一天上涨了201%。

 

估值50亿的网红美妆店,卖我一堆假小样?

 

我也是其中一员,折扣价入手正装,闲鱼出手等量的小样,自己既用了正装又减轻了压力。而金字塔模式的中国,像我这样的人还有很多很多。

 

那么问题来了,既然小样已经开始形成独立市场,大牌为何不直接售卖小样?是没嗅到商机吗?

 

实际上早有化妆品企业着手操办起了小样的生意,例如欧莱雅集团就开了个小美盒旗舰店,卖的就是小样套盒,销售量真不赖,一千到两万不等。

 

估值50亿的网红美妆店,卖我一堆假小样?

 

天猫U先试用也是个女孩们薅小样的绝佳平台,甚至许多营销号都改头换面做起了发布讯息来积攒流量的生意。

 

估值50亿的网红美妆店,卖我一堆假小样?

 

可能会有人不解,为啥有那么多女孩会买大牌小样啊?也有人嘲讽,钱没到,就别臭这个美。

 

但实际上,买正品前先买小样试用,早就成了新的消费正义。

 

估值50亿的网红美妆店,卖我一堆假小样?

 

股神巴菲特曾经说过:“价格是你付出的,价值才是你得到的。”

 

而小样,就能让你用最少的价格提前获得最大的价值。

 

现实里你可能距离月入五万的白领精英还有一些差距,但原本五千元的贵妇精华,现在用一两百就能亲自感受。在这种听上去“买了就是赚了”的逻辑下,哪个女孩会不心动?

 

估值50亿的网红美妆店,卖我一堆假小样?

 

另一方面,如何挑选到一款适合自己的产品本就是一门玄学。

 

哪怕你在剁手一款贵妇精华前已经做足了功课,都难保长痘、过敏、起皮……而购置香水更是一场豪赌,就算你盲撸的是一款被评为二十世纪最伟大的香水,到你身上都可能只是股臭肥皂水味。

 

因此,买正品前先试用小样,就能让你的钱包和皮肤要承担的试错成本骤然下降。

 

估值50亿的网红美妆店,卖我一堆假小样?

 

更重要的是,购物清单里的生活必需品虽然能帮你的生活重复得很稳固,但没能给你带来一丝新鲜的体验;消费新的化妆品、衣服、包包却能让你整个人一下子就焕然一新。

 

但在一线大城市打拼的多数女孩们,还要抠抠搜搜地攒着工资交下个季度的房租,哪有多余的钱享受呢?

 

得一步一步慢慢来,先买小样用着,以后挣钱了再买大牌正品也不迟。坐在末班地铁上的通勤女孩们一下子就想通了,整颗心都敞亮了起来。

 

可刷了几下手机看到我这篇文章后,女孩们刚敞亮起来的心刹那间又被堵得密不透风。

 

估值50亿的网红美妆店,卖我一堆假小样?

 

面对这件事,我虽然无力反抗它,甚至我都没法100%去判定,这家估值50亿的网红美妆店,是否正在公然售假。

 

但我能做的,就是尽我所能去把这个疑问大声地提出来,并且呼唤更多的人来发问。

 

不是只责问自己是不是肤质太敏感,是不是贪了小便宜,而是要跟这些靠卖小样致富的品牌方要一个答案。

 

就像古装片中的城门,坚固、高大,但只要我们有足够的人,不停地撞,使劲撞,虽然门还没倒塌,但它已经在慢慢变化了。

 

 

转自:https://mp.weixin.qq.com/s/Z2AZgI9Z1SCT8cpKNzrFZQ

深圳原副市长唐杰:深圳不可能用2000平方公里解决2000万人的住房!

深圳的经验就是构建市场化、法治化、国际化的营商环境,把这“三化”从口号变成政府施政标准、官员行为准则,打造一个服务型政府、可问责的政府,在现有政治架构下实现了法治的市场经济。

 

 

2020年是深圳经济特区成立四十周年,10月11日,中共中央办公厅、国务院办公厅印发了《深圳建设中国特色社会主义先行示范区综合改革试点实施方案(2020-2025年)》(下称《方案》)。

 

《方案》赋予深圳更多自主权,鼓励深圳加快形成全面深化改革、全面扩大开放的新格局,推动更高水平深港合作,增强深圳在粤港澳大湾区建设中的核心引擎功能,努力创建社会主义现代化强国的城市范例。

 

40年前,深圳是一个毗邻香港的小渔村,GDP不足香港的0.2%,如今,这座移民城市拥有2000万人口,GDP已超过香港,并成为中国内地人均GDP最高的城市。

 

40年间,深圳实现了产业结构的跃迁,从一个比拼廉价劳动力的加工装配基地,到“山寨”一切的模仿性制造中心,再到拥有全球影响力的创新中心。人类历史上,还没有哪座城市能用如此短的时间取得如此大的进步。

 

深圳做对了什么,有哪些可以复制到内地的经验,从特区到先行示范区,深圳还能不能继续创造奇迹?

 

深圳原副市长唐杰:深圳不可能用2000平方公里解决2000万人的住房!

唐杰。图/受访者提供

 

2020年10月21日,《财经》记者就上述问题专访了深圳市原副市长、哈尔滨工业大学(深圳)经济管理学院教授唐杰。

 

唐杰1995年获南开大学经济学博士后不久即南下深圳,1997年进入深圳市政府,2015年从深圳市副市长任上退休,是深圳奇迹的见证者、亲历者和思考者。

 

深圳原副市长唐杰:深圳不可能用2000平方公里解决2000万人的住房!

 

01 

市场化、法治化、国际化

 

《财经》:深圳从经济特区变成了先行示范区,两个概念有何不同,是文字游戏还是内涵变了?

 

唐杰:特区一词带有改革开放初期的特殊印记,代表敢闯敢试、敢为人先的时代精神。后来中央决定开发浦东时就没继续叫特区,叫新区了,滨海新区、雄安新区等等。先行示范区意味着进入新的时期,要有新的实验。

 

改革相当长一段时间都是摸着石头过河,十八大以来我们强调要建立一个完善的制度,十八届三中全会做出了全面深化改革的决定。拿盖房子打比喻的话,房子的四梁八柱已经有了,但窗户怎么建、门怎么装,这些不能都统一设计,需要各地自己探索。示范区就要承担这样一个探索功能,而且要形成可复制经验。

 

《财经》:那么深圳特区40年形成的可复制可推广经验是什么?

 

唐杰:深圳的经验就是构建市场化、法治化、国际化的营商环境,把市场化、法治化、国际化从口号变成了政府施政标准、官员行为准则,在现有政治架构下实现了法治的市场经济。坚持市场化、法治化、国际化,这次也写进了深圳先行示范区综合改革实施方案。

 

《财经》:市场化、法治化、国际化是怎样从口号变成行为准则的?能否结合您在深圳从政18年的经历具体谈谈?

 

唐杰让市场在资源配置中起决定性作用,目标已经有了,但目标要量化。如果嘴上说转变增长方式,但投资率50%,说转变政府行为,但非税收入占50%,那不就是空喊口号吗?

 

我们的改革是这样,过去一切生产过程全部是计划,后来计划变成了审批,行政干预从直接计划变成间接审批。审批的理由是防止重复建设,但是你看看这些年,钢铁、石化、电视机……所有过剩严重的行业都是严格审批的行业,审批的过剩比市场过剩严重得多。

 

深圳政府不一样的地方在于,我们认识到自己掌握的市场信息不可能比华为多,所以不会乱指挥企业。反过来,政府指挥企业,企业亏损了,政府就得兜底。

 

市场起决定作用已经说了很多年,但是看看现实,政府干预经济的现象是不是仍普遍存在,为什么会一直存在?

 

深圳经常被拿来跟另一个东部沿海大城市做比较,确实两个城市都是改革开放的排头兵,我自己的对比,两地政府最大的不同:一边说我就要管事,因为我的干部素质高,道德水准也高;一边说我的干部素质高,但我不觉得他们能经受得了诱惑,所以管事越少越好。

 

这些年两地都办了很多创业孵化器,差别在于,深圳的孵化器大部分都是私营公司,本身就是要赚钱的,政府是引导鼓励;另一个城市的孵化器是政府派保姆办的幼儿园,幼儿园办得很好,职业水准很高,但赚不赚钱保姆不考虑。在深圳,一般政府做一件事,马上就会想我今天给你一个东西,你能不能发展起来,我后续还有没有负担?深圳的政府思维就是创投思维,创造环境让企业降低创业风险。

 

深圳政府很早就认识到权力集中就有套利空间,所以深圳政府处理政企关系时尽量市场化。

 

在深圳,如果哪个部门出现了腐败,这个部门此后的制度建设方向肯定是分权、放权。

 

《财经》:全世界都知道中国的政府是经济建设型政府、有为才有位的政府,深圳政府大规模分权放权之后,工作重点是什么?

 

唐杰:研究、规划、服务。我在深圳政府工作18年,得到的最大机会就是学习机会。因为时间不用花在行政审批上,就会关注深圳五年后怎么样,十年后怎么样,香港怎么样,广州怎么样,区域间怎么协同发展?其他人也一样,时间花在做研究方案上。在深圳,政府要决策一件事,最后上会讨论的一定不止一两个方案,任何大的决策,一定都做过方案比选。

 

像我们的规划委员会,市领导的任何一个想法,比如想向东发展该怎么做?规划委马上把向东发展的方案给你,因为当年已经做好了。但他会告诉你当年的方案有什么东西没做,没做是因为缺什么条件,现在需要配齐什么。所以深圳的城市建设不会翻烧饼,新领导来了,说前领导错了要重来,然后再来一个又说上一个错了。

 

有一次我问一位内地到深圳挂职的干部感受是什么?他说深圳政府花在讨论上的时间太长、不敢决策,否则深圳会发展得更快。但深圳的决策程序就是这样的,必须充分讨论,不仅政府内部,涉及到的社会相关利益方也要参与讨论。深圳政府的做事理念是:很少只有利没有弊的事情,慎重决策、科学决策,每一次走一小步、不停往前走、不断打补丁。

 

深圳政府不仅自己做研究,还发动外脑做研究。每到年初深圳就有一个景观,中国第一流的研究机构都到深圳竞标课题,光是社科课题,深圳政府每年都要花几千万,这已经形成了习惯。我今天还接到一个医改课题的评议邀请,课题提交方有同济、复旦、清华,来的都是一流大学。

 

《财经》:那么深圳还需要继续减少行政对市场的干预、继续下放审批权吗?

 

唐杰:其实市场不是一个简单的生产商、消费者加政府的三方关系,市场是多层次的多方关系,市场的另外一个重要载体是行业协会、社会组织。深圳有大量行业协会,它们的功能一是制定行业标准,二是维持行业自律,三是研究培训。在政府手中的市场职能,政府不能简单交给企业,而应交给行业协会。我建议你们去深圳市民政局采访,看看深圳怎样培育发展社会中介组织。为什么一些内地城市来深圳看了后发现学不了,就因为它们缺失社会中介组织这一环。或者,虽然有行业协会,但领导由退休政府官员担任,协会思维行为方式也与政府无异。

 

下一步全面深化改革,政府自身的改革是关键。比如事业单位编制,全国有几千万,其实就是影子政府。你想想如果吃财政饭的事业编制没有了,还会有正处级医院副局级校长吗,大学的行政化还能延续吗?大学创新能力不足是这几年反复讨论的话题。为什么总书记跟科学家讲初心?科学家的初心就对科学保持着好奇心。但行政化天然遏制好奇心,因为行政化的特征是整齐划一,创新是创造差异性,有内在矛盾。

 

这方面的改革已经在做,深圳会走得更快,深圳已经开始推行公务员雇员制了。五年之后,你就会看到行政化的趋势发生根本性变化。当然这个过程中要解决社保待遇公平过渡的问题,否则就会引发社会矛盾。

 

《财经》:法治化在深圳有哪些体现?

 

唐杰其实政府的法治化可以用两个直观的标准来衡量:第一政府官员是不是天天被企业围着找,第二财政收入中有多少是非税收入?企业做事离不开政府、财政非税收入过高,都意味着该地区的法治化程度低。

 

深圳的政府是个服务型政府,可问责的政府。行政诉讼,深圳规定被诉部门的一把手必须到庭,当时一把手们气得不行,堂堂区长局长成被告了,大家一开始都很不适应,政府的败诉率也高,至少七八成。但几年之后就反过来了,政府的胜诉率八成以上,为什么?因为政府所有的决策过程都有法律根据,所有的行政行为都依法而来,那还会败诉吗?

 

法规本身的质量、法规是否公开透明也非常重要。在深圳,政府文件都要经过立法机构审查,审查通过才能实施,并且必须公开透明。

 

深圳的中小企业发展得很好,这很大程度上得益于深圳市人大2010年出台的《深圳经济特区中小企业发展促进条例》,条例里,政府要给中小企业提供什么信息、解决什么困难都说得很清楚。人大可以拿这个条例到政府来巡视检查工作,这个就是外部监督了,比政府内部监督更有效。在深圳,来自人大等的对法规实施的外部检查督查已经是常态。

 

深圳的创业投资产业发展得也很好,甚至创业投资这个词也是深圳的发明。这很大程度上得益于深圳市人大2003年出台的《深圳经济特区创业投资条例》。深圳是最早给VC(风险投资)、PE(私募股权投资)立法的,取消了当时的虚假注册资本罪和抽逃注册资本罪,创投企业从注册资本制变为承诺资本制。

 

创投条例的立法过程花了五年时间,这期间创投产业已经在发展,深圳市政府并不懂怎么搞创投产业,靠的是深圳市创投协会,这是个自发形成的民间组织,协会建规则、立标准、做培训,一手推动了行业的发展。在创投条例的立法过程中,创投协会也贡献了大量专业知识。

 

这样的例子还有很多,40年间,聚沙成塔,深圳慢慢形成了多方平衡寻求社会公正的过程,形成了不找市长找市场、不找关系上法院的社会风气和营商环境。

 

《财经》:对深圳法治化做出突出贡献的市领导是哪几位?

 

唐杰:市场化法治化在深圳是一以贯之的,每一任领导都做出过贡献。如果非要让我具体说,我认为李灏(1985年-1993年任深圳市长、市委书记)的贡献最大。总书记讲40年来深圳首创了1000多项改革举措,实现了由经济体制改革到全面深化改革的历史性跨越。这1000多项举措里,很多都是李灏主政时期出台的,可以说,李灏把深圳带入了系统化制度创新时期。

 

深圳有句深入人心的口号——来了就是深圳人。如果没有深圳首任市长、市委书记梁湘(1981-1985年在任)的一个决定,这个口号就不可能变成现实。梁湘坚持,政府系统内必须说普通话,也就是确立普通话为深圳的官方语言,当初多数人主张讲广东话,梁湘自己就是广东人,但他认为普通话便于融合多元文化。

 

深圳原副市长唐杰:深圳不可能用2000平方公里解决2000万人的住房!

 

02 

深港一体化下的开放与融合

 

《财经》:深圳先行示范区综改方案要求深圳推动更高水平的深港合作。香港目前形势微妙,如果香港衰落了,深圳会怎样?

 

唐杰深港是互相依存关系,过去40年,没有香港就没有深圳,香港不好了,深圳肯定也不会好。但到了今天,没有深圳,香港的转型会更加困难。

 

香港出问题一个重要原因是不少年轻人觉得没前途。香港700万人,300万劳动力,香港特区政府10月20日发布的最新统计数字显示,香港失业率在7月-9月升至6.4%,为近16年来的高点,其中年轻人的失业率更高。

 

在内地,越来越多年轻人选择创业,但香港房价贵,店面租金也贵,香港年轻一代创业成本高,就业机会少,就容易引起社会冲突。

 

深圳已经着手为香港年轻人提供更多的就业机会。2017年初,港深创新科技园就在落马洲、河套地区推进,未来会吸引大量香港的科技人才走向深圳。

 

《财经》:深港之间哪些领域最容易加大融合力度?

 

唐杰:边检、金融、法律、行业标准都有很大空间。

 

香港的发展,需要把空间放大到整个大湾区。虽然近在咫尺,但多半香港人从没来过深圳,香港人度假也更愿意南下而非北上,其中一个原因是往返一趟太麻烦。粤港澳大湾区的开放程度比欧盟28国低多了,我们是一个国家,他们是28个国家。为什么深港两地的身份证不能通用,还要额外办证呢?提高湾区居民生活便利化与一国两制不冲突。大湾区要实现经济一体化,海关边检需要率先改革。我们能不能设定一个目标:把大湾区的通关便利度提高到欧盟的水平?既然是一国,那么双方都要创造一国的氛围,香港人到了内地,处处会感觉自己和内地人不一样,深圳人到上海会有这种感觉吗?

 

深圳前海为什么对港人有吸引力?因为香港律师执照在这里有效,香港律师可以在这里执业。在前海仲裁,适用香港法律。将来香港的会计师、律师的执业权限有望扩大到深圳全市。深圳金融局正与港澳金融协会合作编制可互相认可的金融标准,互认标准的行业还会继续扩大。深港互联互通,各行业都一样,谁的标准好、谁的标准更国际化,就用谁的,这个不是大问题(编者注:10月22日,国务院办公厅印发《香港法律执业者和澳门执业律师在粤港澳大湾区内地九市取得内地执业资质和从事律师职业试点办法》)。

 

香港和深圳互补的地方很多,两地的差别就是美国东西两岸的差别。香港是国际金融中心,资金量大、成本低。香港金融业竞争力很强,1.5%的贷款年利率,银行居然还能赚钱,内地5%的年利率就算是低息贷款。深圳有一些企业拿到了香港的低息贷款,这算是深圳企业一个红利,但拿到钱的毕竟是少数。深圳应该欢迎香港银行业北上展业,目前深圳中小微企业融资成本比香港企业高近3倍。

 

另一方面,深圳是内地首屈一指的制造业中心和创新创业中心,无论对香港金融业还是高校,都是广阔天地。香港弹丸之地,却有五所大学进入世界前100名,科技人才密集。但香港缺乏产业基础,香港高校的科研成果不好落地,深圳正好互补。香港高校到深圳办学也前景广阔,目前香港中文大学深圳校区已经挺成功,深圳两所本地大学——深圳大学和南方科技大学,也借鉴了很多香港高校的办学理念,这两所大学近年来的上升速度很快。

 

2020年10月下旬,香港特首林郑月娥接受采访,谈到将与深圳推出“联合政策包”,深港互利合作前景乐观。

 

深圳原副市长唐杰:深圳不可能用2000平方公里解决2000万人的住房!

 

03 

不可能用2000平方公里

解决2000万人的住房

 

《财经》:深圳的高房价一直受全国关注,先行示范区综改方案支持深圳在土地管理制度上深化探索。但我们研究后发现,政策无法释放出足够的住宅建设用地,供小于求,未来深圳房价仍将处于高位。

 

唐杰深圳2000万人口的住房问题不可能在2000平方公里内得到解决,全球范围内都没有这样的先例。解决深圳住房问题,必须改变长期以来的行政城市观念,走向经济城市——城市之间的行政区划不能隔断城市之间的经济一体化,鼓励生产要素跨城市流动,减缓目前极为突出的城市之间人口过疏或过密的状况。

 

深圳规划院调查发现,在深圳、惠州、东莞的交界处已经形成了一个跨行政区的城市经济带,人口达到1000万,人口和经济密度要比深圳中心区低很多,房价也比深圳低很多。深圳和周边城市应顺应这一趋势,打破行政边界,率先探索从行政城市走向经济城市。

 

另一方面,深圳正在进一步推进多层次的住房体系,增加政府支持下的保障房、长租公寓的供给,缓解中心城区住房压力。

 

《财经》:示范区方案要求深圳增强在粤港澳大湾区建设中的核心引擎功能,这是否意味着在跨行政区轨道交通建设上深圳会有更大自主权?这对房价有何影响?

 

唐杰:城市人口密集度越高,房价就越贵,随着轨道交通从中心市区向外延伸,房价也会等比例下降。深圳市政府和行业协会正在积极布局,打破行政边界,规划建设多条轨道交通线连接东莞和惠州。这是中国城市建设中从行政城市走向经济城市的重要探索。

 

但是只靠交通便利还不足以吸引中心城区人口搬到周边,接下来要以核心城市为轴心逐渐实现公共服务均等化,这需要更高层面的统筹。比如,需要中央多个部门协调配合,解决好城市间社保打通的问题,解决好教育支出分享的问题,解决好医院建设与经费保障的问题。

 

房地产问题比较复杂,我们不能一出现市场失灵就代之以行政管制,很难想象简单粗糙的行政手段能够取代复杂的市场机制,实现房地产市场的供求均衡。

转自:https://mp.weixin.qq.com/s/JoArMJzPRUVFF4dkI4AYGg

​Python 如何仅用 5000 行代码,实现强大的 logging 模块?

 

者:肖恩

来源:游戏不存在

Python 的 logging 模块实现了灵活的日志系统。整个模块仅仅 3 个类,不到 5000 行代码的样子,学习它可以加深对程序日志的了解,本文分下面几个部分:

  • logging 简介
  • logging API 设计
  • 记录器对象 Logger
  • 日志记录对象 LogRecord
  • 处理器对象 Hander
  • 格式器对象 Formatter
  • 滚动日志文件处理器
  • 小结
  • 小技巧

logging 简介

本次代码使用的是 python 3.8.5 的版本,官方中文文档 3.8.8 。参考链接中官方中文文档非常详细,建议先看一遍了解日志使用。

功能
logging-module logging的API
Logger 日志记录器对象类,可以创建一个对象用来记录日志
LogRecord 日志记录对象,每条日志记录都封装成一个日志记录对象
Hander 处理器对象,负责日志输出到流/文件的控制
Formatter 格式器,负责日志记录的格式化
RotatingFileHandler 按大小滚动的日志文件记录器
TimedRotatingFileHandler 按时间滚动的日志文件处理器

我们主要研究日志如何输出到标准窗口这一主线;日志的配置,日志的线程安全及各种特别的Handler等支线可以先忽略。

logging API 设计

先看看日志使用:

import logging

logging.basicConfig(level=logging.INFO, format='%(levelname)-8s %(name)-10s %(asctime)s %(message)s')
lang = {"name""python""age":20}
logging.info('This is a info message %s', lang)
logging.debug('This is a debug message')
logging.warning('This is a warning message')

logger = logging.getLogger(__name__)
logger.warning('This is a warning')

输出内容如下:

INFO     root       2021-03-04 00:03:53,473 This is a info message {'name''python''age': 20}
WARNING  root       2021-03-04 00:03:53,473 This is a warning message
WARNING  __main__   2021-03-04 00:03:53,473 This is a warning

可以看到 logging 的使用非常方便,模块直接提供了一组API。

root = RootLogger(WARNING)  # 默认提供的logger
Logger.root = root
Logger.manager = Manager(Logger.root)

def debug(msg, *args, **kwargs): # info,warning等api类似
    if len(root.handlers) == 0:
        basicConfig()  # 默认配置
    root.debug(msg, *args, **kwargs)

def getLogger(name=None):
    if name:
        return Logger.manager.getLogger(name)  # 创建特定的logger
    else:
        return root  # 返回默认的logger

这种API的提供方式,我们在requests中也有看到。api中很重要的设置config的方式:

def basicConfig(**kwargs):
    ...
    if handlers is None:
        filename = kwargs.pop("filename", None)
        mode = kwargs.pop("filemode"'a')
        if filename:
            h = FileHandler(filename, mode)
        else:
            stream = kwargs.pop("stream", None)
            h = StreamHandler(stream)  # 默认的handler
        handlers = [h]
    dfs = kwargs.pop("datefmt", None)
    style = kwargs.pop("style"'%')
    fs = kwargs.pop("format", _STYLES[style][1])
    fmt = Formatter(fs, dfs, style)  # 生成formatter
    for h in handlers:
        if h.formatter is None:
            h.setFormatter(fmt)
        root.addHandler(h)  # 设置root的handler
    level = kwargs.pop("level", None)
    if level is not None:
        root.setLevel(level)  # 设置日志级别

可以看到,日志的配置主要包括下面几项:

  • level 日志级别
  • format 信息格式化模版
  • filename 输出到文件
  • datefmt %Y-%m-%d %H:%M:%S,uuu 时间的格式模版
  • style [%,{,$] 格式样板

演示代码输出中,可以看到debug日志没有显示,是因为 debug < info:

CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0

记录器对象 Logger

查看Logger之前,先看logger对象的管理类Manager

_loggerClass = Logger

class Manager(object):
    def __init__(self, rootnode):
        self.root = rootnode
        self.disable = 0
        self.loggerDict = {}  # 所有日志记录对象的字典
    ...
    def getLogger(self, name):
        rv = None
        if name in self.loggerDict:
            rv = self.loggerDict[name]  # 获取已经创建过的同名logger
            ...
        else:
            rv = (self.loggerClass or _loggerClass)(name)  # 创建新的logger
            rv.manager = self
            self.loggerDict[name] = rv
            ...
        return rv

日志过滤器

class Filterer(object):

    def __init__(self):
        self.filters = []

    def addFilter(self, filter):
        self.filters.append(filter)

    def removeFilter(self, filter):
        self.filters.remove(filter)

    def filter(self, record):
        rv = True
        for f in self.filters:  # 过滤日志
            if hasattr(f, 'filter'):
                result = f.filter(record)
            else:
                result = f(record) # assume callable - will raise if not
            if not result:
                rv = False
                break
        return r

核心的 Logger 实际上只是一个控制中心:

class Logger(Filterer):  # logger可以过滤日志
    def __init__(self, name, level=NOTSET):
        Filterer.__init__(self)
        self.name = name
        self.level = _checkLevel(level)
        self.parent = None  # 日志可以有层级
        self.propagate = True
        self.handlers = []  # 可以输出到多个handler
        self.disabled = False  # 可以关闭
        self._cache = {}
    
    def debug(self, msg, *args, **kwargs):  # 输出debug日志
        if self.isEnabledFor(DEBUG):
            self._log(DEBUG, msg, args, **kwargs)

logger可以判断日志级别:

def isEnabledFor(self, level):
    if self.disabled:
        return False

    try:
        return self._cache[level]
    except KeyError:
        try:
            if self.manager.disable >= level:
                is_enabled = self._cache[level] = False
            else:
                is_enabled = self._cache[level] = (
                    level >= self.getEffectiveLevel()
                )
        return is_enabled

def getEffectiveLevel(self):
    logger = self
    while logger:
        if logger.level:
            return logger.level
        logger = logger.parent
    return NOTSET

日志输出:

def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False,
         stacklevel=1):
    ...
    fn, lno, func = "(unknown file)", 0, "(unknown function)"
    ...
    # 生成日志记录
    record = self.makeRecord(self.name, level, fn, lno, msg, args,
                             exc_info, func, extra, sinfo)
    # 使用handler处理日志
    self.handle(record)

日志记录的生产,就是创建一个LogRecord对象:

_logRecordFactory = LogRecord

def makeRecord(self, name, level, fn, lno, msg, args, exc_info,
               func=None, extra=None, sinfo=None):
    ...
    rv = _logRecordFactory(name, level, fn, lno, msg, args, exc_info, func,
                         sinfo)
    ...
    return rv

使用logger对象的所有handler处理日志:

def handle(self, record):
    c = self
    found = 0
    while c:
        for hdlr in c.handlers:  # 使用所有的handler处理日志
            found = found + 1
            if record.levelno >= hdlr.level:
                hdlr.handle(record)

root-logger 的handler是在config中配置的:

def basicConfig(**kwargs):
    ...
    root.addHandler(h)  # 设置root的handler

日志记录对象 LogRecord

日志记录对象非常简单:

class LogRecord(object):
    def __init__(self, name, level, pathname, lineno,
                 msg, args, exc_info, func=None, sinfo=None, **kwargs):
        ct = time.time()
        self.name = name  # logger名称
        self.msg = msg  # 日志标识信息
        ...
        self.args = args  # 变量
        self.levelname = getLevelName(level)
        ...
    
    def getMessage(self):
        msg = str(self.msg)
        if self.args:
            msg = msg % self.args  # 格式化消息
        return msg

处理器对象 Hander

顶级Handler定义了Handler的模版方法

class Handler(Filterer):  # 处理器也可以过滤日志
    def __init__(self, level=NOTSET):
        Filterer.__init__(self)
        self._name = None
        self.level = _checkLevel(level)  # handler也有日志级别
        self.formatter = None
        _addHandlerRef(self)
        self.createLock()
        
    def handle(self, record):  # 处理日志
        rv = self.filter(record)  # 过滤日志
        if rv:
            self.acquire()  # 申请锁
            try:
                self.emit(record)  # 提交记录,由不同子类实现 
            finally:
                self.release()  # 释放锁
        return rv

默认的console流 StreamHandler

class StreamHandler(Handler):

    terminator = 'n'  # 自动换行

    def __init__(self, stream=None):
        Handler.__init__(self)
        if stream is None:
            stream = sys.stderr  # 默认使用stderr输出
        self.stream = stream
    
    def emit(self, record):
        try:
            msg = self.format(record)  # 格式化日志记录
            stream = self.stream
            stream.write(msg + self.terminator)  # 写日志
            self.flush()  # 刷新写缓存
        except Exception:
            ...
    
    def format(self, record):
        if self.formatter:
            fmt = self.formatter
        else:
            fmt = _defaultFormatter
        return fmt.format(record)  # 使用格式化器格式化日志记录

为什么使用stderr,可以看下面的测试中的输出都是到console:

print("haha")
print("fatal error", file=sys.stderr)
sys.stderr.write("fatal errorn")

格式器对象 Formatter

格式化器主要使用Formatter和Style实现

class Formatter(object):
    def __init__(self, fmt=None, datefmt=None, style='%', validate=True):
        self._style = _STYLES[style][0](fmt)
        self._fmt = self._style._fmt
        self.datefmt = datefmt
    
    def format(self, record):
        record.message = record.getMessage()
        s = self.formatMessage(record)
        return s
        
    def formatMessage(self, record):
        return self._style.format(record)  # 格式化

Style类

class PercentStyle(object):

    default_format = '%(message)s'
    asctime_format = '%(asctime)s'
    asctime_search = '%(asctime)'
    validation_pattern = re.compile(r'%(w+)[#0+ -]*(*|d+)?(.(*|d+))?[diouxefgcrsa%]', re.I)

    def __init__(self, fmt):
        self._fmt = fmt or self.default_format

    def usesTime(self):
        return self._fmt.find(self.asctime_search) >= 0

    def validate(self):
        """Validate the input format, ensure it matches the correct style"""
        if not self.validation_pattern.search(self._fmt):
            raise ValueError("Invalid format '%s' for '%s' style" % (self._fmt, self.default_format[0]))

    def _format(self, record):
        return self._fmt % record.__dict__  # 格式化日志记录对象

    def format(self, record):
        try:
            return self._format(record)
        except KeyError as e:
            raise ValueError('Formatting field not found in record: %s' % e)

滚动日志文件处理器

线上的日志持续输出到一个文件的话,会让文件巨大,即有加剧了丢失的风险,也难以处理。通常有按照大小滚动或者按照日期滚动的方法,这个功能非常重要。先看滚动日志处理器模版:

class BaseRotatingHandler(logging.FileHandler):
    def emit(self, record):
        try:
            if self.shouldRollover(record): # 判断是否需要滚动
                self.doRollover()  # 滚动日志
            logging.FileHandler.emit(self, record)  # 输出日志
        except Exception:
            self.handleError(record)
    
    def rotate(self, source, dest):
        if not callable(self.rotator):
            if os.path.exists(source):
                os.rename(source, dest)  # 重命名日志文件
        else:
            self.rotator(source, dest)

按大小滚动 RotatingFileHandler

按照文件大小滚动的处理器:

class RotatingFileHandler(BaseRotatingHandler):

    def __init__(self, filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=False):
        if maxBytes > 0:
            mode = 'a'
        BaseRotatingHandler.__init__(self, filename, mode, encoding, delay)
        self.maxBytes = maxBytes  # 单个文件大小上限
        self.backupCount = backupCount  # 日志备份数量
        
    def doRollover(self):  # 执行滚动
        if self.stream:
            self.stream.close()  # 关闭当前的流
            self.stream = None
        if self.backupCount > 0:
            for i in range(self.backupCount - 1, 0, -1):
                sfn = self.rotation_filename("%s.%d" % (self.baseFilename, i))
                dfn = self.rotation_filename("%s.%d" % (self.baseFilename,
                                                        i + 1))
                if os.path.exists(sfn):
                    if os.path.exists(dfn):
                        os.remove(dfn)
                    os.rename(sfn, dfn)
            dfn = self.rotation_filename(self.baseFilename + ".1")
            if os.path.exists(dfn):
                os.remove(dfn)
            self.rotate(self.baseFilename, dfn)  # 重命名文件
        if not self.delay:
            self.stream = self._open()  # 如果shouldRollover延迟,可以打开新的流

    def shouldRollover(self, record):  # 判断是否需要滚动
        if self.stream is None:  # 立即打开流
            self.stream = self._open()
        if self.maxBytes > 0:   
            msg = "%sn" % self.format(record)
            self.stream.seek(0, 2)  #due to non-posix-compliant Windows feature
            if self.stream.tell() + len(msg) >= self.maxBytes:  # 判断大小
                return 1
        return 0

文件大小滚动就是在记录日志时候判断文档是否超过上限,超过则重命名旧日志,生成新日志。

按照日期滚动 TimedRotatingFileHandler

按照日期滚动的处理器:

class TimedRotatingFileHandler(BaseRotatingHandler):
    def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None):
        BaseRotatingHandler.__init__(self, filename, 'a', encoding, delay)
        self.when = when.upper()
        self.backupCount = backupCount
        self.utc = utc
        self.atTime = atTime
        # 日期设置,支持多种方式
        if self.when == 'S':
            self.interval = 1 # one second
            self.suffix = "%Y-%m-%d_%H-%M-%S"
            self.extMatch = r"^d{4}-d{2}-d{2}_d{2}-d{2}-d{2}(.w+)?$"
        ...

        self.extMatch = re.compile(self.extMatch, re.ASCII)
        self.interval = self.interval * interval # multiply by units requested
        filename = self.baseFilename
        if os.path.exists(filename):
            t = os.stat(filename)[ST_MTIME]  # 最后修改时间
        else:
            t = int(time.time())
        self.rolloverAt = self.computeRollover(t)  # 提前计算终止时间

    def computeRollover(self, currentTime):
        # 判断的方法还是很长很复杂的,先pass

    def shouldRollover(self, record):
        t = int(time.time())
        if t >= self.rolloverAt:  # 判断是否到期
            return 1
        return 0

    def doRollover(self):
        ...
        dfn = self.rotation_filename(self.baseFilename + "." +
                                     time.strftime(self.suffix, timeTuple))
        #  滚动日志文件
        if os.path.exists(dfn):
            os.remove(dfn)
        self.rotate(self.baseFilename, dfn)
        if self.backupCount > 0:
            for s in self.getFilesToDelete():
                os.remove(s)
        ...
        # 计算下一个时间点
        newRolloverAt = self.computeRollover(currentTime)
        ...
        self.rolloverAt = newRolloverAt

日期滚动就是计算最后时间点,超过时间点则重新生成新的日志文件。

小结

logging的处理逻辑大概是这样的:

  • 创建Logger对象,提供API,用来接收应用程序日志
  • Logger对象包括多个Handler
  • 每个Handler有一个Formatter对象
  • 每条日志都会生成一个LogRecord对象
  • 使用不同的Handler对象将LogRecored对象提交到不同的流
  • 每个日志对象通过Formatter格式化输出
  • 可以使用按日期/文件大小的方式进行日志文件的滚动记录

小技巧

覆盖对象的 __reduce__ 方法,让对象支持reduce函数:

class RootLogger(Logger):
    def __init__(self, level):
        Logger.__init__(self, "root", level)

    def __reduce__(self):
        return getLogger, ()

线程锁的创建和释放:

_lock = threading.RLock()

def _acquireLock():
    if _lock:
        _lock.acquire()

def _releaseLock():
    if _lock:
        _lock.release()

线程锁的使用:

def addHandler(self, hdlr):
    _acquireLock()
    try:
        self.handlers.append(hdlr)
    finally:
        _releaseLock()

def removeHandler(self, hdlr):
    _acquireLock()
    try:
        self.handlers.remove(hdlr)
    finally:
        _releaseLock()

参考链接

  • Logging in Python https://realpython.com/python-logging/
  • 日志操作手册 https://docs.python.org/zh-cn/3.8/howto/logging-cookbook.html#cookbook-rotator-namer
  • Python 的日志记录工具 https://docs.python.org/zh-cn/3.8/library/logging.html

转自:https://mp.weixin.qq.com/s/7wiDBdGRRQymJz5oeyvboQ