param
param copied to clipboard
Feature: Support for binary strings
Currently param.String works with strings ("string"
), but throws an error when a binary string b"binary string"
is used.
When accessing hardware devices (e.g. a camera via usb), the returned strings are very often binary strings.
So I would like to suggest a new param type: param.BinaryString
(I had a look into the source code myself and tried to understand how it works, but I failed...)
Sure. BinaryString or maybe BinaryBuffer or ByteArray. I assume you'd copy the String implementation but then change the type to a bytearray instead.
Somehow I overlooked the String class while scrolling through the github file in the browser. I found the definition of the class now, so I guess I will be able to adapt the code.
Oh, I should have warned you that unlike nearly every other Parameter, String is defined in parameterized.py
and not __init__.py
, because of a bootstrapping issue that means that we need it declared to be able to have Parameterized objects have a name parameter. I think that's the only parameter that is special like that; ByteArray (or whatever) would go into __init__.py
like all the rest.
My suggestion of a Bytes class (based on the String class):
class Bytes(Parameter):
"""
A Bytes Parameter, with a default value and optional regular expression (regex) matching.
A class similar to the String class, but instead of type basestring (Python2) or str (recent Python3) (e.g. 'string')
the type bytes (e.g. b'bytes') is used.
"""
def __init__(self, default=b"", regex=None, allow_None=False, **kwargs):
super(Bytes, self).__init__(default=default, allow_None=allow_None, **kwargs)
def _validate(self, val):
if self.allow_None and val is None:
return
if not isinstance(val, bytes):
raise ValueError("Bytes '%s' only takes a byte string value."%self.name)
if self.regex is not None and re.match(self.regex, val) is None:
raise ValueError("Bytes '%s': '%s' does not match regex '%s'."%(self.name,val,self.regex))
Simple test:
class Test(param.Parameterized):
b = Bytes(b'bytes')
test = Test()
test.b
Test similar to the given test in the String documentation:
class IPAddress(Bytes):
'''IPv4 address as bytes (dotted decimal notation)'''
def __init__(self, default=b"0.0.0.0", allow_None=False, **kwargs):
ip_regex = b'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
super(IPAddress, self).__init__(default=default, regex=ip_regex, **kwargs)
ipaddress = IPAddress()
ipaddress.default
Looks good. Could probably use that with some magic numbers to have a PNG, JPG, etc. Parameter!
Meanwhile I am working with param.Parameter
like this:
class TestWithParameter(param.Parameterized):
b = param.Parameter()
@param.depends('b', watch=True)
def on_b(self):
print('b changed to "{}"'.format(self.b))
test_with_parameter = TestWithParameter(b=b'test')
print(test_with_parameter.b)
test_with_parameter.b = b'test2'
When run in a notebookcell the output is
b'test'
b changed to "b'test2'"
A separate class Bytes seems still more elegant to me, but it is not strictly necessary (unless the bytes type shall be checked and enforced).
Implemented in #542 🎉