function download(text, name, type) {
var a = document.getElementById("a");
var file = new Blob([text], {type: type});
a.href = URL.createObjectURL(file);
a.download = name;
}
<a href="" id="a">click here to download your file</a>
<button onclick="download('file text', 'myfilename.txt', 'text/plain')">Create file</button>
И вы затем загрузите файл, поместив атрибут загрузки в тег привязки.
Причина, по которой я как это лучше, чем создание URL-адреса данных, так это то, что вам не нужно делать большой длинный URL-адрес, вы можете просто создать временный URL-адрес.
Хотя я бы настоятельно рекомендовал не делать этого и применять только определенные методы с использованием абстрактных базовых классов ( http://docs.python.org/2/library/abc.html ), это возможно.
Вот пример того, как сделать что-то подобное: http://www.artima.com/weblogs/viewpost.jsp?thread=101605
# mm.py
registry = {}
class MultiMethod(object):
def __init__(self, name):
self.name = name
self.typemap = {}
def __call__(self, *args):
types = tuple(arg.__class__ for arg in args) # a generator expression!
function = self.typemap.get(types)
if function is None:
raise TypeError("no match")
return function(*args)
def register(self, types, function):
if types in self.typemap:
raise TypeError("duplicate registration")
self.typemap[types] = function
def multimethod(*types):
def register(function):
function = getattr(function, "__lastreg__", function)
name = function.__name__
mm = registry.get(name)
if mm is None:
mm = registry[name] = MultiMethod(name)
mm.register(types, function)
mm.__lastreg__ = function
return mm
return register
if hasattr(function, "__lastreg__"):
function = function.__lastreg__
И код с его использованием:
import mm
@mm.multimethod(int)
def spam(a):
print 'Calling the int method'
print '%s: %r' % (type(a), a)
@mm.multimethod(float)
def spam(a):
print 'Calling the float method'
print '%s: %r' % (type(a), a)
spam(5)
spam(5.0)
Пример вывода:
Calling the int method
<type 'int'>: 5
Calling the float method
<type 'float'>: 5.0
Поскольку я не единственный в этом проекте, я не хочу, чтобы кто-то вызывал функцию RegisterAsListener с неправильным типом данных
blockquote>Полностью документировал функцию, затем пусть неправильные параметры выдают исключения. Пользователь
RegisterAListener
должен иметь возможность использовать документацию, чтобы знать, какие данные ожидает функция, и - если заданы неверные параметры - результирующее исключение должно дать понять, что сделал пользовательRegisterAListener
.