There's a whole matrix of these and I'm wondering why the matrix is
currently sparse rather than implementing them all. Or rather, why we
can't stack them as:
class foo(object):
@classmethod
@property
def bar(cls, ...):
...
Essentially the permutation are, I think:
{'unadorned'|abc.abstract}{'normal'|static|class}{method|property|non-callable
attribute}.
concreteness
implicit first arg
type
name
comments
{unadorned}
{unadorned}
method
def foo():
exists now
{unadorned} {unadorned} property
@property
exists now
{unadorned} {unadorned} non-callable attribute
x = 2
exists now
{unadorned} static
method @staticmethod
exists now
{unadorned} static property @staticproperty
proposing
{unadorned} static non-callable attribute {degenerate case -
variables don't have arguments}
unnecessary
{unadorned} class
method @classmethod
exists now
{unadorned} class property @classproperty or @classmethod;@property
proposing
{unadorned} class non-callable attribute {degenerate case - variables
don't have arguments}
unnecessary
abc.abstract {unadorned} method @abc.abstractmethod
exists now
abc.abstract {unadorned} property @abc.abstractproperty
exists now
abc.abstract {unadorned} non-callable attribute
@abc.abstractattribute or @abc.abstract;@attribute
proposing
abc.abstract static method @abc.abstractstaticmethod
exists now
abc.abstract static property @abc.staticproperty
proposing
abc.abstract static non-callable attribute {degenerate case -
variables don't have arguments} unnecessary
abc.abstract class method @abc.abstractclassmethod
exists now
abc.abstract class property @abc.abstractclassproperty
proposing
abc.abstract class non-callable attribute {degenerate case -
variables don't have arguments} unnecessary
I think the meanings of the new ones are pretty straightforward, but in
case they are not...
@staticproperty - like @property only without an implicit first
argument. Allows the property to be called directly from the class
without requiring a throw-away instance.
@classproperty - like @property, only the implicit first argument to the
method is the class. Allows the property to be called directly from the
class without requiring a throw-away instance.
@abc.abstractattribute - a simple, non-callable variable that must be
overridden in subclasses
@abc.abstractstaticproperty - like @abc.abstractproperty only for
@staticproperty
@abc.abstractclassproperty - like @abc.abstractproperty only for
@classproperty
--rich
At the moment, the array module of the standard library allows to
create arrays of different numeric types and to initialize them from
an iterable (eg, another array).
What's missing is the possiblity to specify the final size of the
array (number of items), especially for large arrays.
I'm thinking of suffix arrays (a text indexing data structure) for
large texts, eg the human genome and its reverse complement (about 6
billion characters from the alphabet ACGT).
The suffix array is a long int array of the same size (8 bytes per
number, so it occupies about 48 GB memory).
At the moment I am extending an array in chunks of several million
items at a time at a time, which is slow and not elegant.
The function below also initializes each item in the array to a given
value (0 by default).
Is there a reason why there the array.array constructor does not allow
to simply specify the number of items that should be allocated? (I do
not really care about the contents.)
Would this be a worthwhile addition to / modification of the array module?
My suggestions is to modify array generation in such a way that you
could pass an iterator (as now) as second argument, but if you pass a
single integer value, it should be treated as the number of items to
allocate.
Here is my current workaround (which is slow):
def filled_array(typecode, n, value=0, bsize=(1<<22)):
"""returns a new array with given typecode
(eg, "l" for long int, as in the array module)
with n entries, initialized to the given value (default 0)
"""
a = array.array(typecode, [value]*bsize)
x = array.array(typecode)
r = n
while r >= bsize:
x.extend(a)
r -= bsize
x.extend([value]*r)
return x
Hi,
For technical reasons, many functions of the Python standard libraries
implemented in C have positional-only parameters. Example:
-------
$ ./python
Python 3.7.0a0 (default, Feb 25 2017, 04:30:32)
>>> help(str.replace)
replace(self, old, new, count=-1, /) # <== notice "/" at the end
...
>>> "a".replace("x", "y") # ok
'a'
>>> "a".replace(old="x", new="y") # ERR!
TypeError: replace() takes at least 2 arguments (0 given)
-------
When converting the methods of the builtin str type to the internal
"Argument Clinic" tool (tool to generate the function signature,
function docstring and the code to parse arguments in C), I asked if
we should add support for keyword arguments in str.replace(). The
answer was quick: no! It's a deliberate design choice.
Quote of Yury Selivanov's message:
"""
I think Guido explicitly stated that he doesn't like the idea to
always allow keyword arguments for all methods. I.e. `str.find('aaa')`
just reads better than `str.find(needle='aaa')`. Essentially, the idea
is that for most of the builtins that accept one or two arguments,
positional-only parameters are better.
"""
http://bugs.python.org/issue29286#msg285578
I just noticed a module on PyPI to implement this behaviour on Python functions:
https://pypi.python.org/pypi/positional
My question is: would it make sense to implement this feature in
Python directly? If yes, what should be the syntax? Use "/" marker?
Use the @positional() decorator?
Do you see concrete cases where it's a deliberate choice to deny
passing arguments as keywords?
Don't you like writing int(x="123") instead of int("123")? :-) (I know
that Serhiy Storshake hates the name of the "x" parameter of the int
constructor ;-))
By the way, I read that "/" marker is unknown by almost all Python
developers, and [...] syntax should be preferred, but
inspect.signature() doesn't support this syntax. Maybe we should fix
signature() and use [...] format instead?
Replace "replace(self, old, new, count=-1, /)" with "replace(self,
old, new[, count=-1])" (or maybe even not document the default
value?).
Python 3.5 help (docstring) uses "S.replace(old, new[, count])".
Victor
I just spent a few minutes staring at a bug caused by a missing comma
-- I got a mysterious argument count error because instead of foo('a',
'b') I had written foo('a' 'b').
This is a fairly common mistake, and IIRC at Google we even had a lint
rule against this (there was also a Python dialect used for some
specific purpose where this was explicitly forbidden).
Now, with modern compiler technology, we can (and in fact do) evaluate
compile-time string literal concatenation with the '+' operator, so
there's really no reason to support 'a' 'b' any more. (The reason was
always rather flimsy; I copied it from C but the reason why it's
needed there doesn't really apply to Python, as it is mostly useful
inside macros.)
Would it be reasonable to start deprecating this and eventually remove
it from the language?
--
--Guido van Rossum (python.org/~guido)
Hi All,
I find importing defaultdict from collections to be clunky and it seems
like having a default should just be an optional keyword to dict. Thus,
something like,
d = dict(default=int)
would be the same as
from collections import defaultdict
d = defaultdict(int)
Any thoughts?
Thanks,
++Steve
Hello everyone,
I'm shortly writing to you about a reflection I lately made upon the
current functioning of __str__ for the time's class.
Before expressing my thought and proposal, I want to make sure we all agree
on a simple and clear fact:
the __str__ magic method is used to give a literal and human-readable
representation to the object (unlike __repr__).
Generally this is true across the python panorama. It's not true for the
time class, for example.
*>>> import time>>> a = time.localtime()>>>
a.__str__()'time.struct_time(tm_year=2017, tm_mon=3, tm_mday=8, tm_hour=16,
tm_min=6, tm_sec=16, tm_wday=2, tm_yday=67, tm_isdst=0)'*
Well, don't get me wrong: the main aim of the __str__ method has been
accomplished but, imho, not in the most pythonic way.
I just wanted to ask you: what do you think about re-writing the __str__ of
the time class so it would return something like
ISO 8601 [https://en.wikipedia.org/wiki/ISO_8601] format? Wouldn't it be
more meaningful? Especially in the JS-everywhere-era
it could be more more productive.
*TL;DR*
__str__ for dates should return a human-readable date format (eg:
https://en.wikipedia.org/wiki/ISO_8601)
I'm waiting for your opinions.
Thank you for your time and ideas!
Francesco Franchina
Hello,
After some french discussions about this idea, I subscribed here to
suggest adding a new string litteral, for regexp, inspired by other
types like : u"", r"", b"", br"", f""…
The regexp string litteral could be represented by : re""
It would ease the use of regexps in Python, allowing to have some regexp
litterals, like in Perl or JavaScript.
We may end up with an integration like :
>>> import re
>>> if re".k" in 'ok':
... print "ok"
ok
>>>
Regexps are part of the language in Perl, and the rather complicated
integration of regexp in other languages, especially in Python, is
something that comes up easily in language comparing discussion.
I've always felt JavaScript integration being half the way it should,
and new string litterals types in Python (like f"") looked like a good
compromise to have a tight integration of regexps without asking to make
them part of the language (as I imagine it has already been discussed
years ago, and obviously denied…).
As per XKCD illustration, using a regexp may be a problem on its own,
but really, the "each-language a new and complicated approach" is
another difficulty, of the level of writing regexps I think. And then,
when you get the trick for Python, it feels to me still to much letters
to type regarding the numerous problems one can solve using regexps.
I know regexps are slower than string-based workflow (like .startswith)
but regexps can do the most and the least, so they are rapide to come up
with, once you started to think with them. As Python philosophy is to
spare brain-cycles, sacrificing CPU-cycles, allowing to easily use
regexps is a brain-cycle savior trick.
What do you think ?
--
Simon Descarpentries
+336 769 702 53
http://acoeuro.com
This keeps on coming up in one form or another - either someone
multiplies a list of lists and ends up surprised that they're all the
same, or is frustrated with the verbosity of the alternatives.
Can we use the matmul operator for this?
class List(list):
def __matmul__(self, other):
return [copy.copy(x) for x in self for _ in range(other)]
>>> x = List([[0]*4]) @ 2
>>> x
[[0, 0, 0, 0], [0, 0, 0, 0]]
>>> x[0][0] = 1
>>> x
[[1, 0, 0, 0], [0, 0, 0, 0]]
If this were supported by the built-in list type, it would be either of these:
>>> x = [[0] * 4] @ 2
>>> x = [[0] @ 4] @ 4
(identical functionality, as copying an integer has no effect).
The semantics could be either as shown above (copy.copy()), or
something very simple and narrow like "lists get shallow-copied, other
objects get referenced".
Thoughts?
ChrisA
> To me, 'pop' implies mutation. Tuples do not have a pop method, and it
> is not obvious to me that either tuples or frozensets should. What are > the use cases that are not better served by converting to list or set?
> --
> Terry Jan Reedy
1) coverting to set or list is O(n) in time
2) if I have to keep the old copy,
standard set solution will be O(n) both in time and space!
working examples:
1) priority queue:
insert and pop occur
2) share immutable data to difference subroutines:
each one can modify local copy safely and concurrency.
Hi Pythonistas,
yet again today I ended up writing:
d = [[0] * 5 for _ in range(10)]
And wondered, why don't we have a way to repeat other than looping over
range() and using a dummy variable? This seems like a rather common thing
to do, and while the benefit doesn't seem much, something like this would
be much prettier and more pythonic than using underscore variable:
d = [[0] * 5 repeat_for 10]
And could obviously be used outside of comprehensions too:
repeat_for 3:
print('Attempting to reconnect...')
if reconnect():
break
else:
print('Unable to reconnect :(')
sys.exit(0)
I chose to use repeat_for instead of repeat because it's way less likely to
be used as a variable name, but obviously other names could be used like
loop_for or repeat_times etc.
Thoughts?