2011-10-02 56 views
0

我有一個Python腳本signalgen.py使用方程播放音頻,但我想能夠硬編碼公式存儲在eq1.txt中的文件或選擇一個文件並導入該公式。
我遇到的問題是:從文件導入代碼到Python並添加文件對話框

1)我怎麼能硬代碼的文件,它的路徑正確,因此將播放方程音頻

我得到一個錯誤 回溯(最近通話最後): 文件 「signalgen.py」,線路484,在need_data v + =(基準* self.sig_level) 類型錯誤:不能由類型 '浮動'

特定塊的非INT序列乘以代碼,我認爲是造成問題

def equation_import_function(self,t,f): 
    fileobj=open("/home/rat/eq1.txt","r") 
    eqdata =fileobj.read() #read whole file 
    fileobj.close() 
    #return math.tan(2.0*math.pi*f*t) 
    return eqdata 

我在eq1.txt文件 - > math.tan(2.0 * math.pi * F * T)

2)如何添加一個文件打開對話框是這行代碼能夠選擇一個文件並導入公式。

PS我使用Ubuntu 10.04(Linux)或公式將是幾頁長,這是我想將它們導入到Python從文本文件的原因

這裏就是整個代碼,如果你想看看在我使用下方或引擎收錄看出,其中包括行號是什麼http://pastebin.com/HZg0Jhaw

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

# *************************************************************************** 
# * Copyright (C) 2011, Paul Lutus          * 
# *                   * 
# * This program is free software; you can redistribute it and/or modify * 
# * it under the terms of the GNU General Public License as published by * 
# * the Free Software Foundation; either version 2 of the License, or  * 
# * (at your option) any later version.         * 
# *                   * 
# * This program is distributed in the hope that it will be useful,  * 
# * but WITHOUT ANY WARRANTY; without even the implied warranty of  * 
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the   * 
# * GNU General Public License for more details.       * 
# *                   * 
# * You should have received a copy of the GNU General Public License  * 
# * along with this program; if not, write to the       * 
# * Free Software Foundation, Inc.,          * 
# * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.    * 
# *************************************************************************** 

# version date 01-12-2011 

VERSION = '1.1' 

import re, sys, os 

import gobject 
gobject.threads_init() 
import gst 
import gtk 
gtk.gdk.threads_init() 
import time 
import struct 
import math 
import random 
import signal 
import webbrowser 

class Icon: 
    icon = [ 
    "32 32 17 1", 
    " c None", 
    ". C#2A2E30", 
    "+ C#333739", 
    "@ C#464A4C", 
    "# C#855023", 
    "$ C#575A59", 
    "% C#676A69", 
    "& C#CC5B00", 
    "* C#777A78", 
    "= C#DB731A", 
    "- C#8A8C8A", 
    "; C#969895", 
    "> C#F68C22", 
    ", C#A5A7A4", 
    "' C#F49D4A", 
    ") C#B3B5B2", 
    "! C#DEE0DD", 
    "      &&&&&&& ", 
    "     &&&===='''''& ", 
    "     &'''''====&'& ", 
    "    +++++&'&&&&& &'& ", 
    "   [email protected]$%****&'&+  &'& ", 
    "  [email protected]**%[email protected][email protected]&'&*@+ &'& ", 
    "  [email protected]**@+++++++&'&@**@+ &'& ", 
    "  +$*$+++++++++&'&++$*$+ &'& ", 
    "  @*@++++++++++&'&[email protected]#&&&'& ", 
    " +*@++++++++#&&&'&+++#=''''& ", 
    " +*$++++++++#=''''&+++&'>>>'& ", 
    " @*+++++++++&'>>>'&+++#='''= ", 
    " +%[email protected]#='''=#@@++#&&&# ", 
    " +*@[email protected]@@#&&&#@@@@@[email protected]*+ ", 
    " +*[email protected]@@@[email protected]$%[email protected]@@@++*+ ", 
    " +*[email protected]@[email protected];,,*@@*[email protected]@@+*+ ", 
    " +*@[email protected]@@%!!!!,;@$*[email protected]@@*+ ", 
    " +%[email protected]@+)!!!),-*+-%[email protected]$%+ ", 
    " [email protected]*[email protected]@@+-!!!,;-%@;%%$$+*@+ ", 
    " +*@[email protected]@@@+$*-*%@+*-%%[email protected]@*+ ", 
    " ++*@[email protected]@@$$%@[email protected]%;;*%%[email protected]$+ ", 
    " [email protected]%[email protected]@@$$%*;;;;-*%%%@**+ ", 
    " .+$%@@@$$$*******%$$*-+. ", 
    "  [email protected]%%@@$$*@*@%%%$%-%+.  ", 
    "  [email protected]%$$$$$$%%%%[email protected]+.  ", 
    "  [email protected]@$%*****%+++  ", 
    "   [email protected]  ", 
    "   @--%@[email protected]$*-%+   ", 
    "   +%,))),;%+.   ", 
    "    ++++++.   ", 
    "        ", 
    "        " 
    ] 

# this should be a temporary hack 

class WidgetFinder: 
    def localize_widgets(self,parent,xmlfile): 
    # an unbelievable hack made necessary by 
    # someone unwilling to fix a year-old bug 
    with open(xmlfile) as f: 
     for name in re.findall('(?s) id="(.*?)"',f.read()): 
     if re.search('^k_',name): 
      obj = parent.builder.get_object(name) 
      setattr(parent,name,obj) 

class ConfigManager: 
    def __init__(self,path,dic): 
    self.path = path 
    self.dic = dic 

    def read_config(self): 
    if os.path.exists(self.path): 
     with open(self.path) as f: 
     for record in f.readlines(): 
      se = re.search('(.*?)\s*=\s*(.*)',record.strip()) 
      if(se): 
      key,value = se.groups() 
      if (key in self.dic): 
       widget = self.dic[key] 
       typ = type(widget) 
       if(typ == list): 
       widget[0] = value 
       elif(typ == gtk.Entry): 
       widget.set_text(value) 
       elif(typ == gtk.HScale): 
       widget.set_value(float(value)) 
       elif(typ == gtk.Window): 
       w,h = value.split(',') 
       widget.resize(int(w),int(h)) 
       elif(typ == gtk.CheckButton or typ == gtk.RadioButton or typ == gtk.ToggleButton): 
       widget.set_active(value == 'True') 
       elif(typ == gtk.ComboBox): 
       if(value in widget.datalist): 
        i = widget.datalist.index(value) 
        widget.set_active(i) 
       else: 
       print "ERROR: reading, cannot identify key %s with type %s" % (key,type(widget)) 

    def write_config(self): 
    with open(self.path,'w') as f: 
     for key,widget in sorted(self.dic.iteritems()): 
     typ = type(widget) 
     if(typ == list): 
      value = widget[0] 
     elif(typ == gtk.Entry): 
      value = widget.get_text() 
     elif(typ == gtk.HScale): 
      value = str(widget.get_value()) 
     elif(typ == gtk.Window): 
      _,_,w,h = widget.get_allocation() 
      value = "%d,%d" % (w,h) 
     elif(typ == gtk.CheckButton or typ == gtk.RadioButton or typ == gtk.ToggleButton): 
      value = ('False','True')[widget.get_active()] 
     elif(typ == gtk.ComboBox): 
      value = widget.get_active_text() 
     else: 
      print "ERROR: writing, cannot identify key %s with type %s" % (key,type(widget)) 
      value = "Error" 
     f.write("%s = %s\n" % (key,value)) 

    def preset_combobox(self,box,v): 
    if(v in box.datalist): 
     i = box.datalist.index(v) 
     box.set_active(i) 
    else: 
     box.set_active(0) 

    def load_combobox(self,obj,data): 
    if(len(obj.get_cells()) == 0): 
     # Create a text cell renderer 
     cell = gtk.CellRendererText() 
     obj.pack_start(cell) 
     obj.add_attribute (cell, "text", 0) 
    obj.get_model().clear() 
    for s in data: 
     obj.append_text(s.strip()) 
    setattr(obj,'datalist',data) 

class TextEntryController: 
    def __init__(self,parent,widget): 
    self.par = parent 
    self.widget = widget 
    widget.connect('scroll-event',self.scroll_event) 
    widget.set_tooltip_text('Enter number or:\n\ 
    Mouse wheel: increase,decrease\n\ 
    Shift/Ctrl/Alt: faster change') 

    def scroll_event(self,w,evt): 
    q = (-1,1)[evt.direction == gtk.gdk.SCROLL_UP] 
    # magnify change if shift,ctrl,alt pressed 
    for m in (1,2,4): 
     if(self.par.mod_key_val & m): q *= 10 
    s = self.widget.get_text() 
    v = float(s) 
    v += q 
    v = max(0,v) 
    s = self.par.format_num(v) 
    self.widget.set_text(s) 

class SignalGen: 
    M_AM,M_FM = range(2) 
    W_SINE,W_TRIANGLE,W_SQUARE,W_SAWTOOTH,W_EQUATION_IMPORT = range(5) 
    waveform_strings = ('Sine','Triangle','Square','Sawtooth', 'Equation_Import') 
    R_48000,R_44100,R_22050,R_16000,R_11025,R_8000,R_4000 = range(7) 
    sample_rates = ('48000','44100','22050','16000', '11025', '8000', '4000') 
    def __init__(self): 
    self.restart = False 
    # exit correctly on system signals 
    signal.signal(signal.SIGTERM, self.close) 
    signal.signal(signal.SIGINT, self.close) 
    # precompile struct operator 
    self.struct_int = struct.Struct('i') 
    self.max_level = (2.0**31)-1 
    self.gen_functions = (
     self.sine_function, 
     self.triangle_function, 
     self.square_function, 
     self.sawtooth_function, 
     self.equation_import_function 
    ) 
    self.main_color = gtk.gdk.color_parse('#c04040') 
    self.sig_color = gtk.gdk.color_parse('#40c040') 
    self.mod_color = gtk.gdk.color_parse('#4040c0') 
    self.noise_color = gtk.gdk.color_parse('#c040c0') 
    self.pipeline = False 
    self.count = 0 
    self.imod = 0 
    self.rate = 1 
    self.mod_key_val = 0 
    self.sig_freq = 440 
    self.mod_freq = 3 
    self.sig_level = 100 
    self.mod_level = 100 
    self.noise_level = 100 
    self.enable = True 
    self.sig_waveform = SignalGen.W_SINE 
    self.sig_enable = True 
    self.sig_function = False 
    self.mod_waveform = SignalGen.W_SINE 
    self.mod_function = False 
    self.mod_mode = SignalGen.M_AM 
    self.mod_enable = False 
    self.noise_enable = False 
    self.sample_rate = SignalGen.R_22050 
    self.left_audio = True 
    self.right_audio = True 
    self.program_name = self.__class__.__name__ 
    self.config_file = os.path.expanduser("~/." + self.program_name) 
    self.builder = gtk.Builder() 
    self.xmlfile = 'signalgen_gui.glade' 
    self.builder.add_from_file(self.xmlfile) 
    WidgetFinder().localize_widgets(self,self.xmlfile) 
    self.k_quit_button.connect('clicked',self.close) 
    self.k_help_button.connect('clicked',self.launch_help) 
    self.k_mainwindow.connect('destroy',self.close) 
    self.k_mainwindow.set_icon(gtk.gdk.pixbuf_new_from_xpm_data(Icon.icon)) 
    self.title = self.program_name + ' ' + VERSION 
    self.k_mainwindow.set_title(self.title) 
    self.tooltips = { 
     self.k_sample_rate_combobox : 'Change data sampling rate', 
     self.k_left_checkbutton : 'Enable left channel audio', 
     self.k_right_checkbutton : 'Enable right channel audio', 
     self.k_sig_waveform_combobox : 'Select signal waveform', 
     self.k_mod_waveform_combobox : 'Select modulation waveform', 
     self.k_mod_enable_checkbutton : 'Enable modulation', 
     self.k_sig_enable_checkbutton : 'Enable signal', 
     self.k_noise_enable_checkbutton : 'Enable white noise', 
     self.k_mod_am_radiobutton : 'Enable amplitude modulation', 
     self.k_mod_fm_radiobutton : 'Enable frequency modulation', 
     self.k_quit_button : 'Quit %s' % self.title, 
     self.k_enable_checkbutton : 'Enable output', 
     self.k_help_button : 'Visit the %s Web page' % self.title, 
    } 
    for k,v in self.tooltips.iteritems(): 
     k.set_tooltip_text(v) 
    self.config_data = { 
     'SampleRate' : self.k_sample_rate_combobox, 
     'LeftChannelEnabled' : self.k_left_checkbutton, 
     'RightChannelEnabled' : self.k_right_checkbutton, 
     'SignalWaveform' : self.k_sig_waveform_combobox, 
     'SignalFrequency' : self.k_sig_freq_entry, 
     'SignalLevel' : self.k_sig_level_entry, 
     'SignalEnabled' : self.k_sig_enable_checkbutton, 
     'ModulationWaveform' : self.k_mod_waveform_combobox, 
     'ModulationFrequency' : self.k_mod_freq_entry, 
     'ModulationLevel' : self.k_mod_level_entry, 
     'ModulationEnabled' : self.k_mod_enable_checkbutton, 
     'AmplitudeModulation' : self.k_mod_am_radiobutton, 
     'FrequencyModulation' : self.k_mod_fm_radiobutton, 
     'NoiseEnabled' : self.k_noise_enable_checkbutton, 
     'NoiseLevel' : self.k_noise_level_entry, 
     'OutputEnabled' : self.k_enable_checkbutton, 
    } 
    self.cm = ConfigManager(self.config_file,self.config_data) 
    self.cm.load_combobox(self.k_sig_waveform_combobox,self.waveform_strings) 
    self.k_sig_waveform_combobox.set_active(self.sig_waveform) 
    self.cm.load_combobox(self.k_mod_waveform_combobox,self.waveform_strings) 
    self.k_mod_waveform_combobox.set_active(self.mod_waveform) 
    self.cm.load_combobox(self.k_sample_rate_combobox,self.sample_rates) 
    self.k_sample_rate_combobox.set_active(self.sample_rate) 
    self.k_sig_freq_entry.set_text(self.format_num(self.sig_freq)) 
    self.k_sig_level_entry.set_text(self.format_num(self.sig_level)) 
    self.k_mod_freq_entry.set_text(self.format_num(self.mod_freq)) 
    self.k_mod_level_entry.set_text(self.format_num(self.mod_level)) 
    self.k_noise_level_entry.set_text(self.format_num(self.noise_level)) 
    self.k_main_viewport_border.modify_bg(gtk.STATE_NORMAL,self.main_color) 
    self.k_sig_viewport_border.modify_bg(gtk.STATE_NORMAL,self.sig_color) 
    self.k_mod_viewport_border.modify_bg(gtk.STATE_NORMAL,self.mod_color) 
    self.k_noise_viewport_border.modify_bg(gtk.STATE_NORMAL,self.noise_color) 
    self.sig_freq_cont = TextEntryController(self,self.k_sig_freq_entry) 
    self.sig_level_cont = TextEntryController(self,self.k_sig_level_entry) 
    self.mod_freq_cont = TextEntryController(self,self.k_mod_freq_entry) 
    self.mod_level_cont = TextEntryController(self,self.k_mod_level_entry) 
    self.noise_level_cont = TextEntryController(self,self.k_noise_level_entry) 
    self.k_mainwindow.connect('key-press-event',self.key_event) 
    self.k_mainwindow.connect('key-release-event',self.key_event) 
    self.k_enable_checkbutton.connect('toggled',self.update_values) 
    self.k_sig_freq_entry.connect('changed',self.update_entry_values) 
    self.k_sig_level_entry.connect('changed',self.update_entry_values) 
    self.k_sig_enable_checkbutton.connect('toggled',self.update_checkbutton_values) 
    self.k_mod_freq_entry.connect('changed',self.update_entry_values) 
    self.k_mod_level_entry.connect('changed',self.update_entry_values) 
    self.k_noise_level_entry.connect('changed',self.update_entry_values) 
    self.k_sample_rate_combobox.connect('changed',self.update_values) 
    self.k_sig_waveform_combobox.connect('changed',self.update_values) 
    self.k_mod_waveform_combobox.connect('changed',self.update_values) 
    self.k_left_checkbutton.connect('toggled',self.update_checkbutton_values) 
    self.k_right_checkbutton.connect('toggled',self.update_checkbutton_values) 
    self.k_mod_enable_checkbutton.connect('toggled',self.update_checkbutton_values) 
    self.k_noise_enable_checkbutton.connect('toggled',self.update_checkbutton_values) 
    self.k_mod_am_radiobutton.connect('toggled',self.update_checkbutton_values) 
    self.cm.read_config() 
    self.update_entry_values() 
    self.update_checkbutton_values() 
    self.update_values() 

    def format_num(self,v): 
    return "%.2f" % v 

    def get_widget_text(self,w): 
    typ = type(w) 
    if(typ == gtk.ComboBox): 
     return w.get_active_text() 
    elif(typ == gtk.Entry): 
     return w.get_text() 

    def get_widget_num(self,w): 
    try: 
     return float(self.get_widget_text(w)) 
    except: 
     return 0.0 

    def restart_test(self,w,pv): 
    nv = w.get_active() 
    self.restart |= (nv != pv) 
    return nv 

    def update_entry_values(self,*args): 
    self.sig_freq = self.get_widget_num(self.k_sig_freq_entry) 
    self.sig_level = self.get_widget_num(self.k_sig_level_entry)/100.0 
    self.mod_freq = self.get_widget_num(self.k_mod_freq_entry) 
    self.mod_level = self.get_widget_num(self.k_mod_level_entry)/100.0 
    self.noise_level = self.get_widget_num(self.k_noise_level_entry)/100.0 

    def update_checkbutton_values(self,*args): 
    self.left_audio = self.k_left_checkbutton.get_active() 
    self.right_audio = self.k_right_checkbutton.get_active() 
    self.mod_enable = self.k_mod_enable_checkbutton.get_active() 
    self.sig_enable = self.k_sig_enable_checkbutton.get_active() 
    self.mod_mode = (SignalGen.M_FM,SignalGen.M_AM)[self.k_mod_am_radiobutton.get_active()] 
    self.noise_enable = self.k_noise_enable_checkbutton.get_active() 

    def update_values(self,*args): 
    self.restart = (not self.sig_function) 
    self.sample_rate = self.restart_test(self.k_sample_rate_combobox, self.sample_rate) 
    self.enable = self.restart_test(self.k_enable_checkbutton,self.enable) 
    self.mod_waveform = self.k_mod_waveform_combobox.get_active() 
    self.mod_function = self.gen_functions[self.mod_waveform] 
    self.sig_waveform = self.k_sig_waveform_combobox.get_active() 
    self.sig_function = self.gen_functions[self.sig_waveform] 
    self.k_sample_rate_combobox.set_sensitive(not self.enable) 
    if(self.restart): 
     self.init_audio() 

    def make_and_chain(self,name): 
    target = gst.element_factory_make(name) 
    self.chain.append(target) 
    return target 

    def unlink_gst(self): 
    if(self.pipeline): 
     self.pipeline.set_state(gst.STATE_NULL) 
     self.pipeline.remove_many(*self.chain) 
     gst.element_unlink_many(*self.chain) 
     for item in self.chain: 
     item = False 
     self.pipeline = False 
     time.sleep(0.01) 

    def init_audio(self): 
    self.unlink_gst() 
    if(self.enable): 
     self.chain = [] 
     self.pipeline = gst.Pipeline("mypipeline") 
     self.source = self.make_and_chain("appsrc") 
     rs = SignalGen.sample_rates[self.sample_rate] 
     self.rate = float(rs) 
     self.interval = 1.0/self.rate 
     caps = gst.Caps(
     'audio/x-raw-int,' 
     'endianness=(int)1234,' 
     'channels=(int)2,' 
     'width=(int)32,' 
     'depth=(int)32,' 
     'signed=(boolean)true,' 
     'rate=(int)%s' % rs) 
     self.source.set_property('caps', caps) 
     self.sink = self.make_and_chain("autoaudiosink") 
     self.pipeline.add(*self.chain) 
     gst.element_link_many(*self.chain) 
     self.source.connect('need-data', self.need_data) 
     self.pipeline.set_state(gst.STATE_PLAYING) 

    def key_event(self,w,evt): 
    cn = gtk.gdk.keyval_name(evt.keyval) 
    if(re.search('Shift',cn) != None): 
     mod = 1 
    elif(re.search('Control',cn) != None): 
     mod = 2 
    elif(re.search('Alt|Meta',cn) != None): 
     mod = 4 
    else: 
     return 
    if(evt.type == gtk.gdk.KEY_PRESS): 
     self.mod_key_val |= mod 
    else: 
     self.mod_key_val &= ~mod 

    def sine_function(self,t,f): 
    return math.sin(2.0*math.pi*f*t) 



    def triangle_function(self,t,f): 
    q = 4*math.fmod(t*f,1) 
    q = (q,2-q)[q > 1] 
    return (q,-2-q)[q < -1] 

    def square_function(self,t,f): 
    if(f == 0): return 0 
    q = 0.5 - math.fmod(t*f,1) 
    return (-1,1)[q > 0] 

    def sawtooth_function(self,t,f): 
    return 2.0*math.fmod((t*f)+0.5,1.0)-1.0 

    def equation_import_function(self,t,f): 
    fileobj=open("/home/rat/eq1.txt","r") 
    eqdata =fileobj.read() #read whole file 
    fileobj.close() 
    #return math.tan(2.0*math.pi*f*t) 
    return eqdata 

    def need_data(self,src,length): 
    bytes = "" 
    # sending two channels, so divide requested length by 2 
    ld2 = length/2 
    for tt in range(ld2): 
     t = (self.count + tt) * self.interval 
     if(not self.mod_enable): 
     datum = self.sig_function(t,self.sig_freq) 
     else: 
     mod = self.mod_function(t,self.mod_freq) 
     # AM mode 
     if(self.mod_mode == SignalGen.M_AM): 
      datum = 0.5 * self.sig_function(t,self.sig_freq) * (1.0 + (mod * self.mod_level)) 
     # FM mode 
     else: 
      self.imod += (mod * self.mod_level * self.interval) 
      datum = self.sig_function(t+self.imod,self.sig_freq) 
     v = 0 
     if(self.sig_enable): 
     v += (datum * self.sig_level) 
     if(self.noise_enable): 
     noise = ((2.0 * random.random()) - 1.0) 
     v += noise * self.noise_level 
     v *= self.max_level 
     v = max(-self.max_level,v) 
     v = min(self.max_level,v) 
     left = (0,v)[self.left_audio] 
     right = (0,v)[self.right_audio] 
     bytes += self.struct_int.pack(left) 
     bytes += self.struct_int.pack(right) 
    self.count += ld2 
    src.emit('push-buffer', gst.Buffer(bytes)) 

    def launch_help(self,*args): 
    webbrowser.open("http://arachnoid.com/python/signalgen_program.html") 

    def close(self,*args): 
    self.unlink_gst() 
    self.cm.write_config() 
    gtk.main_quit() 

app=SignalGen() 
gtk.main() 

回答

1

我之前評論過,但我盯着你的代碼足夠長的時間,有點意識到你正在嘗試做什麼,所以我發佈答案更容易。請參閱cJ Zougloubs的答案,因爲我對他使用imp模塊的建議進行了擴展。 你的公式文件,應該實現一個共同的接口:

# equation1.py 
def eqn(*args): 
    return sum(*args) 

然後你會加載它們使用CJ Zougloubs建議,但有一個共同的接口:

# python_rt.py 
def equation_import_function(self, *args): 
    filepath = '' 
    # filepath = ... do file chooser dialog here ... 

    eq_mod = imp.load_source("equation", filepath) 
    eqdata = eq_mod.eqn(*args) 
    return eqdata 

現在,你必須在你的主代碼的函數可以使用任意數量的參數,要求用戶選擇公式文件,併爲您獲得結果。

編輯爲了解決您的評論更具體

# equation1.py 
import math 

def eqn(*args): 
    f = args[0] 
    t = args[1] 
    return math.tan(2.0*math.pi*f*t) 

而在你的主要工具,你可以使用imp.load_source帶進去。無論你需要什麼方程式爲你的音頻,你可以這樣做:

eq_mod.eqn(f, t) 
+0

我還有的第一個問題是我在哪裏把equation1.py文件中的公式math.tan(2.0 * math.pi * f * t)行放到這裏,以便它將方程式作爲音頻播放? –

+0

我做了一個編輯,向你展示你到底在問什麼。 – jdi

+0

非常感謝:--) –

2

imp模塊將幫助您從乾淨任意文件加載Python代碼塊。

#!/usr/bin/env python 
# equation in equation-one.py 
def eqn(arg): 
    return arg * 3 + 2 

#!/usr/bin/env python 
# your code 

import imp 
path = "equation-one.py" 
eq_mod = imp.load_source("equation", path, open(path)) 

print("Oh the nice stuff in eq_mod: %s" % dir(eq_mod)) 

在您的自定義函數的定義,你可以創建一個文件選擇對話框,讓所選擇的文件路徑,加載使用imp的代碼,並返回導入模塊內的函數的結果。

+0

感謝您的快速響應,但我有點困惑如何適應python腳本。你是否說我需要擺脫(self,t,f):並且不要使用fileobj?我應該用def eqn(math.tan(2.0 * math.pi * f * t))替換math.tan(2.0 * math.pi * f * t):return –

+0

我認爲你想要做的是導入包含Python代碼的自定義公式(imp stuff)並選擇要加載的文件(可以使用http://pygtk.org/pygtk2tutorial/sec-FileChoosers.html) –

+0

這就是正是我在找什麼,但是當我把行 def equation_import_function(self,t,f): 返回math.tan(2.0 * math.pi * f * t) 到eq1.py文件並添加線 進口小鬼 eqpath = 「eq1.py」 eq_mod = imp.load_source( 「方程」,eqpath,開放(eqpath)) 它回來與一個錯誤。也許我應該先開始在signalgen.py中將路徑硬編碼到位於eq1.py中的公式,然後再嘗試使用FileChooser選項加載文件。 –