How to pass a callable as an argument to `functools.partial` - python-3.x

This code
import itertools
import functools
i = itertools.cycle(["1", "2"])
def f1():
return next(i)
def f2(a):
print(a)
f = functools.partial(f2, f1())
f()
f()
produces output 1 1.
Is there an obvious way to prevent calculating f1 when f is created, so result output would be 1 2?

How about using closure instead of functools?
import itertools
i = itertools.cycle(["1", "2"])
def f1():
return next(i)
def f2(a):
print(a)
def wrap(target, fun):
def inner():
target(fun())
return inner
f = wrap(f2, f1)
f() # 1
f() # 2

I was able to achieve the intended output using lambda instead of functools.partial:
import itertools
i = itertools.cycle(["1", "2"])
def f1():
return next(i)
def f2(a):
print(a)
f = lambda: f2(f1())
f()
f()

import itertools
import functools
i = itertools.cycle(["1", "2"])
def f1(a):
print(next(a))
f = functools.partial(f1, i)
f()
f()
Just moved work on argument been passed to the patched function

Related

Why wont this work? - def (function) not being called from main()

I need to be able to use classes, but trying to just get my simple code to work
import pandas as pd, numpy as np
class OutOfCountry7ViewModel():
def pandas_conversion(self):
#from csv import readers
deImport = pd.read_csv("ooc-exceptions.csv")
d1 = pd.read_csv("CS_Out_Of_Country.csv", encoding='windows-1252', parse_dates=True)
d2 = pd.read_csv("sccm-devices.csv", encoding='windows-1252')
d3 = pd.read_csv("CTLDAPRawData.csv", encoding='windows-1252')
#pandas join magic
lj_df1 = pd.merge(d1, d2, left_on="ComputerName", right_on="Name", how="left")
lj_df2 = pd.merge(d2, d3, left_on="PrimaryUser", right_on="Employee Number", how="left")
#lj_df = plj_df1d.join(lj_df2, lsuffix=)
df = (lj_df1)
#print(df)
df.to_csv('CS_Out_of_country_tabl.csv', index=False,header=df.columns, encoding='utf-8')
csv = 'CS_Out_of_country_tabl.csv'
return csv
def main():
pandas_conversion(self)
if __name__ == '__main__':
main()
i keep getting an error, NameError: name 'pandas_conversion' is not defined
Are you trying to do something like this? -
import pandas as pd, numpy as np
class OutOfCountry7ViewModel():
def pandas_conversion(self,csv):
...
def main(self):
self.pandas_conversion(csv)
if __name__ == '__main__':
some_object = OutOfCountry7ViewModel()
some_object.main()
This should work:
a = OutOfCountry7ViewModel()
a.pandas_conversion()
Hope this helped!
Try to remember the semantics and indentation of python.
Unused import numpy
Class/Parent Class has no (), Line 3
class OutOfCountry7ViewModel(): #wrong
class OutOfCountry7ViewModel: #right
There is no need of ()
df = (lj_df1)
#if you using some func then you miss that func name
If you're defining a method in the class you've to add instance self
def main(self):
pandas_conversion(self) #wrong calling func with parameter
I think your code is wrong because in PyCharm, it says def pandas_conversion(self): may be static.
So, your code is incomplete, there is something missing that we can't find.

I am generating Fibonacci series using genrator in python3.8 Why this code is not giving any output?

from __future__ import generators
def fib_gen(n):
x=0
y=1
while 1:
x,y=y,x+y
yield x
if __name__=="__main__":
g=fib_gen(8)
for i in f:
print(f.next())
print(f.next())
Error 1: You put fib_gen in variable g but try to iterate through f
Error 2: next() is static not dynamic, ie: f.next() should be next(f)
But everything can be simplified to:
from __future__ import generators
def fib_gen(n):
x=0
y=1
for i in range(n):
x,y=y,x+y
yield x
if __name__=="__main__":
for i in fib_gen(8):
print(i)

mock multiprocessing Pool.map in testing

I want to write a test case for a method in my code mocking the multiprocessing part using pytest.
This the code and I need to write a test for simulation method.
from multiprocessing import Pool
class Simulation:
def __init__(self, num):
self.num = num
def simulation(self):
pool = Pool(processes=self.num)
val = [1, 2, 3, 4, 5]
res = pool.map(self.sim, val)
return res
def sim(self, val):
return val * val
Here is the test case.
import pytest
from multi import Simulation
#pytest.fixture
def sim():
return Simulation(2)
#pytest.fixture
def mock_map():
def map(self, val1=1, val2=2):
return [val1, val2]
return map
def test_sim(sim, mock_map, monkeypatch):
monkeypatch.setattr('multiprocessing.Pool.map', mock_map)
res = sim.simulation()
assert res == [1,2]
When running the test I get the out put as [1,4,6,16,25] where I need to mock the out put as [1,2].

Multiprocessing error: function not defined

The following returns "NameError: name 'times_2' is not defined", and I can't figure out why:
def pass_data(data): return times_2(data)
def times_2(data): return data*2
import multiprocessing
multiprocessing.pool = Pool()
pool.ncpus = 2
res = pool.map(pass_data, range(5))
print(res)
What I'm actually trying to do is apply a function to a pandas dataframe. However, because I can't use a lambda function to do this:
pool.map(lambda x: x.apply(get_weather, axis=1), df_split)
instead I have this with the following helper methods, but it throws a "NameError: name 'get_weather' is not defined":
def get_weather(df):
*do stuff*
return weather_df
def pass_dataframe(df):
return df.apply(get_weather, axis=1)
results = pool.map(pass_dataframe, df_split)
Try using Pool like this:
from multiprocessing import Pool
def pass_data(data): return times_2(data)
def times_2(data): return data*2
with Pool(processes=4) as pool:
res = pool.map(pass_data, range(5))
print(res)
On Windows:
from multiprocessing import Pool
def pass_data(data): return times_2(data)
def times_2(data): return data*2
if __name__ == '__main__':
with Pool(processes=4) as pool:
res = pool.map(pass_data, range(5))
print(res)
See docs https://docs.python.org/3/library/multiprocessing.html#multiprocessing-programming

Is this the right way to pickle instance methods? If yes, why isn't it in Python 3?

Instance methods can not automatically be pickled in both Python 2 or Python 3.
I need to pickle instance methods with Python 3 and I ported example code of Steven Bethard to Python 3:
import copyreg
import types
def _pickle_method(method):
func_name = method.__func__.__name__
obj = method.__self__
cls = method.__self__.__class__
return _unpickle_method, (func_name, obj, cls)
def _unpickle_method(func_name, obj, cls):
for cls in cls.mro():
try:
func = cls.__dict__[func_name]
except KeyError:
pass
else:
break
return func.__get__(obj, cls)
copyreg.pickle(types.MethodType, _pickle_method, _unpickle_method)
Is this method fool proof for pickling instance methods? Or can some things go horribly wrong? I have tested it with some mock up classes and everything seem to work.
If nothing can go wrong, why isn't it possible in Python 3 to standard pickle instance methods?
I can't actually reproduce the original issue on python 3.5.0, see the following example. It might be worth checking on the latest version to see if it just works out-of-the-box :-)
import pickle
import sys
class Foo:
#staticmethod
def my_func():
return 'Foo.my_func'
class Bar:
pass
if __name__ == '__main__':
if len(sys.argv) > 1 and sys.argv[1] == 'restore':
print('loading pickle')
with open('test.pickle', 'rb') as fp:
restored = pickle.load(fp)
print(restored.baz())
else:
print('saving pickle')
b = Bar()
b.baz = Foo.my_func
with open('test.pickle', 'w+b') as fp:
p = pickle.dump(b, fp)
(test)~/test$ python test.py
saving pickle
(test)~/test$ python test.py restore
loading pickle
Foo.my_func
If you want to pickle class instances (and instance methods), just use dill...
>>> import dill
>>>
>>> class Foo:
... def bar(self, x):
... return self.y + x
... def zap(self, y):
... self.y = y
... y = 1
...
>>> f = Foo()
>>> f.zap(4)
>>> f.monty = 'python'
>>>
>>> _f = dill.dumps(f)
>>> del Foo
>>> del f
>>> f = dill.loads(_f)
>>> f.monty
'python'
>>> f.y
4
>>>
>>> _b = dill.dumps(f.bar)
>>> del f
>>> bar = dill.loads(_b)
>>> bar(4)
8
>>>
dill works when you delete the class object, as seen aboveā€¦ so it also works if you start a fresh python session without the class defined, or if you change the class definition. dill even works when you don't have an instance of the class object, or a class instance available. If you want to see how to do it, look at the dill source code: https://github.com/uqfoundation/dill
Also see related: https://stackoverflow.com/a/21345273/2379433

Resources