代码1:Stream().reduce(lambda a,b:a+b,”)
function.__name__ + '_' + Stream(params) \
.reduce(lambda a, b: str(a) + '_' + str(b), '') \
.get()
结果:
'network_whole_features__测试公司' 注意:只有两个下划线;
network_whole_features + '_' +'测试公司'.reduce(lambda a, b: str(a) + '_' + str(b), '') = network_whole_features + '_' +
**???上述reduce只有一个参数????**
参考这个图解:https://blog.csdn.net/sunjin9418/article/details/53086565
上述过程不是这样:reduce作用的不是三个参数('network_whole_features','_', '测试公司'),否则结果应该是:'network_whole_features','_' >> 'network_whole_features__' ;
'network_whole_features__','测试公司' >> 'network_whole_features___测试公司'
此处有三个下滑线;
可行的解释:传入参数只有一个,默认为lambda中的b,a为空,则,其结果为:'_测试公司';再结合前面的字符表达式,可得到:'network_whole_features__测试公司' ;
In[39]: reduce(lambda x , y : x*y , (1,2))
Out[39]: 2
In[40]: reduce(lambda x , y : x*y , (1,2,3))
Out[40]: 6
reduce(lambda x , y : x*y , (1))
TypeError: reduce() arg 2 must support iteration
表达式:>>> n=5
>>> reduce(lambda x , y : x*y , range(1,n+1))
>>>120 #结果
解释:range(1,6) -------> 1,2,3,4,5
前两个传入表达式,得出结果与后一位运算,周而复始。 # ---reduce只接受两个变量 ----- 类似:(x,y)
即:1*2 ---> 2 2*3 ---->6 6*4 --->24 24*5 --->120 # ---解释 1*2 *3 *4 *5 结果120
/
代码2:json.dumps()
json.dumps不支持类实例的直接序列化,可以json.dumps(dict_obj, ensure_ascii=False, default=lambda x: x.dict)实现;反序列化(json对象反序列化为类)json.loads(json_str, object_hook=dict2student),dict2student需要自定义;
Python语言特定的序列化模块是pickle,但如果要把序列化搞得更通用、更符合Web标准,就可以使用json模块。
json模块的dumps()和loads()函数是定义得非常好的接口的典范。当我们使用时,只需要传入一个必须的参数。但是,当默认的序列化或反序列机制不满足我们的要求时,我们又可以传入更多的参数来定制序列化或反序列化的规则,既做到了接口简单易用,又做到了充分的扩展性和灵活性。
a={u'shareOrPosJudgeDocCnt': 1, u'frJudgedocCnt': 2, u'shareOrPosRevokedCnt': 3, u'frZhixingCnt': 7, u'frRevokedCnt': 4, u'shareOrPosZhixingCnt': 5, u'allLinkJudgedocCnt': 6}
b=JsonUtils.collect_2_json_str(api_res)
结果:
b=u'{"shareOrPosJudgeDocCnt": 1, "frJudgedocCnt": 2, "shareOrPosRevokedCnt": 3, "frZhixingCnt": 7, "frRevokedCnt": 4, "shareOrPosZhixingCnt": 5, "allLinkJudgedocCnt": 6}'
其中,函数:
@staticmethod
def collect_2_json_str(dict_obj):
"""
dict or list 转换json
"""
return json.dumps(dict_obj, ensure_ascii=False, default=lambda x: x.__dict__)
**json.dumps():**
Python的dict对象可以直接序列化为JSON的{},不过,很多时候,我们更喜欢用class表示对象,比如定义Student类,然后序列化:
In[41]: a={'a':0,"haha":2}
In[44]: json.dumps(a)
Out[44]: '{"a": 0, "haha": 2}'
但是,通常我们是一个类:
import json
class Student(object): #__main__.Student
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
s = Student('Bob', 20, 88) #<__main__.Student at 0x7fd5b9787ed0>
print(json.dumps(s))
运行报错:TypeError: <__main__.Student object at 0x7fd5b9787ed0> is not JSON serializable
**错误的原因是Student对象不是一个可序列化为JSON的对象。**
如果连class的实例对象都无法序列化为JSON,这肯定不合理!
**别急,我们仔细看看dumps()方法的参数列表,可以发现,除了第一个必须的obj参数外,dumps()方法还提供了一大堆的可选参数:**
https://docs.python.org/2/library/json.html#json.dumps
这些可选参数就是让我们来定制JSON序列化。前面的代码之所以无法把Student类实例序列化为JSON,是因为默认情况下,dumps()方法不知道如何将Student实例变为一个JSON的{}对象。
可选参数default就是把任意一个对象变成一个可序列为JSON的对象,我们只需要为Student专门写一个转换函数,再把函数传进去即可:
def student2dict(std):# <function __main__.student2dict>
return {
'name': std.name,
'age': std.age,
'score': std.score
}
print(json.dumps(s, default=student2dict))
这样,Student实例首先被student2dict()函数转换成dict,然后再被顺利序列化为JSON。
结果:
In[50]: print(json.dumps(s, default=student2dict))
{"age": 20, "score": 88, "name": "Bob"}
In[51]: a = json.dumps(s, default=student2dict)
In[52]: a
Out[52]: '{"age": 20, "score": 88, "name": "Bob"}'
**注意,json.dumps之后为一个字符串,但是print打印看不出来;**
不过,下次如果遇到一个Teacher类的实例,照样无法序列化为JSON。我们可以偷个懒,**把任意class的实例变为dict:**
**print(json.dumps(s, default=lambda obj: obj.__dict__))**
因为通常class的实例都有一个__dict__属性,它就是一个dict,用来存储实例变量。也有少数例外,比如定义了__slots__的class。
**同样的道理,如果我们要把JSON反序列化为一个Student对象实例,loads()方法首先转换出一个dict对象,然后,我们传入的object_hook函数负责把dict转换为Student实例:**
def dict2student(d):
return Student(d['name'], d['age'], d['score'])
json_str = '{"age": 20, "score": 88, "name": "Bob"}'
print(json.loads(json_str, object_hook=dict2student))
运行结果如下:
<__main__.Student object at 0x10cd3c190>
打印出的是反序列化的Student实例对象。
代码3:get用法
字典a={‘m’:2,’n’:3} ,a.get(‘m’,0)=2,
代码4:
temp_dct= {}
temp_dct[‘count’].append(‘some’)
temp_dct[‘count’] = [‘some’]
temp_dct = {‘count’:[‘some’]}
测试代码学习:
from time import sleep
from unittest import TestCase
from multiprocessing import Lock, Manager
import mock
from api.feature_extract_api_svc import FeatureExtractApiSvc
from biz.biz_utils.cahce_api_wrapper import CacheApiWrapper
from common.helper.domain.process_data import ProcessData
from common.helper.mul_process_helper import MulProcessHelper
from db.db_utils.redis_helper import RedisHelper
class TestCacheApiWrapper(TestCase):
def test_get_api__no_mock(self):
# given
redis_helper = RedisHelper()
redis_helper.delete(u'get_cmp_basic_api__深圳市碧桂投资有限公司')
f_e_api_svc = FeatureExtractApiSvc()
m_p_h = MulProcessHelper()
cache_api_wrapper = CacheApiWrapper()
company_name = u'深圳市碧桂投资有限公司'
self.__add_process_data_list(m_p_h, cache_api_wrapper, f_e_api_svc, company_name, 'p1')
self.__add_process_data_list(m_p_h, cache_api_wrapper, f_e_api_svc, company_name, 'p2')
self.__add_process_data_list(m_p_h, cache_api_wrapper, f_e_api_svc, company_name, 'p3')
self.__add_process_data_list(m_p_h, cache_api_wrapper, f_e_api_svc, company_name, 'p4')
# when
result = m_p_h.flush_process(Lock())
# then
self.assertTrue(result['p1'])
self.assertTrue(result['p2'])
self.assertTrue(result['p3'])
self.assertTrue(result['p4'])
@mock.patch.object(FeatureExtractApiSvc, 'get_cmp_basic_api')
def test_get_api(self, get_cmp_basic_api):
# given
manager = Manager()
self.dct_share = manager.Value('tmp', {})
redis_helper = RedisHelper()
redis_helper.delete(u'get_cmp_basic_api__深圳市碧桂投资有限公司')
def side_effect(*arg):
# 统计调用次数
lock = Lock()
with lock:
temp_dct = dict(self.dct_share.value)
if 'count' not in temp_dct:
temp_dct['count'] = []
temp_dct['count'].append('some')
self.dct_share.value = temp_dct
# 阻塞并返回
sleep(0.1)
return {'result': 'ok'}
get_cmp_basic_api.__name__ = 'get_cmp_basic_api'
get_cmp_basic_api.side_effect = side_effect
m_p_h = MulProcessHelper()
cache_api_wrapper = CacheApiWrapper()
company_name = u'深圳市碧桂投资有限公司'
self.__add_process_data_list_mock(m_p_h, cache_api_wrapper, get_cmp_basic_api, company_name, 'p1')
self.__add_process_data_list_mock(m_p_h, cache_api_wrapper, get_cmp_basic_api, company_name, 'p2')
self.__add_process_data_list_mock(m_p_h, cache_api_wrapper, get_cmp_basic_api, company_name, 'p3')
self.__add_process_data_list_mock(m_p_h, cache_api_wrapper, get_cmp_basic_api, company_name, 'p4')
# when
result = m_p_h.flush_process(Lock())
# then
self.assertEqual(1, len(self.dct_share.value['count']), u'api调用次数')
self.assertEqual('ok', result['p1'][0]['result'])
self.assertEqual('ok', result['p2'][0]['result'])
self.assertEqual('ok', result['p3'][0]['result'])
self.assertEqual('ok', result['p4'][0]['result'])
@staticmethod
def __add_process_data_list(m_p_h, cache_api_wrapper, f_e_api_svc, company_name, key):
m_p_h.add_process_data_list(
ProcessData(
cache_api_wrapper.get_api,
(f_e_api_svc.get_cmp_basic_api, company_name),
key
)
)
@staticmethod
def __add_process_data_list_mock(m_p_h, cache_api_wrapper, get_cmp_basic_api, company_name, key):
m_p_h.add_process_data_list(
ProcessData(
cache_api_wrapper.get_api,
(get_cmp_basic_api, company_name),
key
)
)