Найти - Пользователи
Полная версия: вынести функцию из модуля
Начало » Python для новичков » вынести функцию из модуля
1 2
dd67
Можно ли вынести функцию sF из модуля fun.py во внешний скрипт main.py. Причем, хотелось бы как-то сказать скрипту, что эта функция будет объявлена позже (что-то типа extern sF)?
$ cat fun.py 
#!/usr/bin/python
import numpy as np
import sympy as sp
x,y=sp.symbols('x y')
sF=x**2+y**2
sW=sp.diff(sF,x)+sp.diff(sF,y)
funct_W=sp.lambdify((x,y),sW,modules='numpy')
def elemW(x,y):
if x>y: return funct_W(x,y)
else: return 0.0
W=np.vectorize(elemW)
Дело в том, что будут использоваться различные функции sF и не хочеться писать различные модули, для каждого sF.

FishHook
В Вашем скрипте нету функции sF
fata1ex
Я опять ничего не понял. В питоне все функции - это объекты, поэтому проблем с совпадением имён быть не должно (мне показалось, что проблема именно в этом). Можно сделать функцию (со словарём или еще чем), которая будет по желанию возвращать вам нужный вариант sF. Более того, все ваши функции можно просто загнать в список, по которому потом можно будет бегать. Не знаю, об этом ли вообще.
dd67
FishHook
В Вашем скрипте нету функции sF

я имел ввиду вот это выражение
sF=x**2+y**2
мне может понадобится, например,
sF=x+y
или
sF=x**3+2*(y-1)**2
и так далее.
dd67
хотелось бы видеть следующее. В некотором скрипте main1.py я подключаю модуль fun и опереляю свое выражение для sF,
например
sF=y**5+25*x**3
в другом скрипте main2.py определяю свое sF:
sF=cos(x*y)
и так далее. В каждом maini.py своя своя функция sF. При этом maini.py не подключать к fun.py (только fun.py подключается к главному скрипту maini.py, i=1,2,3,4,…).
fata1ex
Так а в чем проблема-то? Где вопрос? Вы же сами всё описали. Берёте модуль main_i, в котором своя функция sF_i, подключаете модуль fun, работаете с модулем fun.

Не знаю, может это поможет:
>>> def foo(x):
...     return x*x
...     
>>> def bar(x):
...     return x*x*x
...     
>>> def nedomap(func, iterable):
...     return [ func(item) for item in iterable ]
...     
>>> nedomap(foo, range(10))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> nedomap(bar, range(10))
[0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
dd67
fata1ex
Так а в чем проблема-то? Где вопрос? Вы же сами всё описали. Берёте модуль main_i, в котором своя функция sF_i, подключаете модуль fun, работаете с модулем fun.

$ cat main.py 
#!/usr/bin/python
import numpy as np
import sympy as sp
x,y=sp.symbols('x y')
sF=x**2+y**2
from fun import *
x=np.array([1,2,3,4,5])
y=np.array([5,4,3,2,1])
print W(x,y)

$ cat fun.py
#!/usr/bin/python
import numpy as np
import sympy as sp

x,y=sp.symbols('x y')
#sF=x**2+y**2
sW=sp.diff(sF,x)+sp.diff(sF,y)
funct_W=sp.lambdify((x,y),sW,modules='numpy')
def elemW(x,y):
if x>y: return funct_W(x,y)
else: return 0.0
W=np.vectorize(elemW)

if __name__ == "__main__":
x=np.array([1,2,3,4,5])
y=np.array([5,4,3,2,1])
print W(x,y)

$ ./main.py
Traceback (most recent call last):
File "./main.py", line 6, in <module>
from fun import *
File "fun.py", line 7, in <module>
sW=sp.diff(sF,x)+sp.diff(sF,y)
NameError: name 'sF' is not defined

подключать каждое maini.py к fun.py не подходит.
dd67
fata1ex
Не знаю, может это поможет:
>>> def foo(x):
...     return x*x
...     

получается, что мне нужно передать в модуль fun некоторое символьное выражение (математическую функцию) из некоторого главного скрипта.
fata1ex
Так, попробую еще раз сказать то, что сказал выше и еще чуть выше.

Всё что есть в питоне - это объект. Эти объекты вы можете передавать куда угодно и как угодно. Насчет передачи данных из модуля в модуль это явно откуда-то не из области программирования. У вас есть модуль fun, который предоставляет некоторый функционал. Этому модулю для работы нужен объект sF. В модуле fun вы создаете функцию, одним из параметров которой является требуемый sF. В любом другом модуле вы можете подключить созданный fun с функцией и передать в неё любую sF. Это возможность я вам попытался донести кодом выше.

Хм, кажется, я понял. Вы хотите, чтобы основной скрипт, не подлкючая fun, использовал его функционал, передавая требуемую функцию sF. Звучит странно.

Хотя нет:
В некотором скрипте main1.py я подключаю модуль fun
но
При этом maini.py не подключать к fun.py

подключать каждое maini.py к fun.py не подходит.

Короче, или вам нужно знакомиться с основами программирования или мне идти на курсы освоения семантической основы речи собеседника :)

Если коротенько:
#fun.py
  
import numpy as np
import sympy as sp
 
def foo(sF, a, b):
	x, y = sp.symbols('x y')
	sW = sp.diff(sF, x) + sp.diff(sF, y)
	return np.vectorize(lambda x, y: sp.lambdify((x,y), sW, modules='numpy') if x > y else 0.0)(a, b)

# main.py
 
import numpy as np
import sympy as sp
 
from fun import foo
 
x, y = sp.symbols('x y')
 
x=np.array([1,2,3,4,5])
y=np.array([5,4,3,2,1])
 
sF = x ** 2 + y ** 2
print foo(sF, x, y)
 
sF = x + y
print foo(sF, x, y)
dd67
С помощью классов решаемо. Правда коряво: хотелось бы в fun, не инициализировать osF, а, опять же, как-то сказать, что инициализация будет позже (возможно придется разобраться с абстрактным классом в Python и полиморфизмом, если он поддерживается).

$ cat fun.py
#!/usr/bin/python
import numpy as np
import sympy as sp

#sF=x**2+y**2
class csF(object):
def __init__(self,eq):
self.eq=eq
x,y=sp.symbols('x y')
osF=csF(x+y)
sW=sp.diff(osF.eq,x)+sp.diff(osF.eq,y)
funct_W=sp.lambdify((x,y),sW,modules='numpy')
def elemW(x,y):
if x>y: return funct_W(x,y)
else: return 0.0
W=np.vectorize(elemW)

if __name__ == "__main__":
x=np.array([1,2,3,4,5])
y=np.array([5,4,3,2,1])
print W(x,y)

$ cat main.py
#!/usr/bin/python
import numpy as np
import sympy as sp
from fun import *
x,y=sp.symbols('x y')
osF.eq=x**2+y**2
x=np.array([1,2,3,4,5])
y=np.array([5,4,3,2,1])
print W(x,y)

$ ./main.py
[ 0. 0. 0. 2. 2.]
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB