Live data from Hacker News

Notset: A Do-Not-Care value for Python

github.com

31–40 of 41 posts

Re: Notset: A Do-Not-Care value for Python

#31
The sentinel value you've used here is the right solution. It keeps the keyword arguments explicit and gives None its value back. However, it doesn't deserve a module global-to-python to live in. The cases where you use this pattern are broader than just "NotSet".

Good pattern, and it needs to be more widely-known, but it doesn't need to occupy the space of a module on PyPI. ;-)

Re: Notset: A Do-Not-Care value for Python

#32
post #27

Why not just use Ellipsis? That is a good "not set value". It is unique so others' Ellipsis is also your Ellipsis. It is already there, don't need to import anything, do any git pull or such.

Interesting. I love the idea of not having to import an external library, but much like the `NotImplementedError` suggestion, it overloads a value that already has a specific meaning, in this case related to slice-notation. I'd worry that this approach could end up being even more confusing.

Yeah it is a hack but in 6 or 7 years of using Python I haven't once needed to use Ellipsis for its intended purpose. I always end up using it though for "not set" where None is one of the valid set values.

Re: Notset: A Do-Not-Care value for Python

#33

The sentinel value you've used here is the right solution. It keeps the keyword arguments explicit and gives None its value back. However, it doesn't deserve a module global-to-python to live in. The cases where you use this pattern are broader than just "NotSet". Good pattern, and it needs to be more widely-known, but it doesn't need to occupy the space of a module on PyPI. ;-)

I'd love to see this integrated into the language and live along side of `None` (I can dream, can't I?)

But until then, how can two different libraries agree to use the exact same instance of `NotSet` without some standard package defining it?

The goal is really to be able to 'proxy' this do-not-care condition from applications into libraries in a standardized way.

Re: Notset: A Do-Not-Care value for Python

#34

I can't remember the specifics offhand, but I used the built-in value "NotImplemented" to address a problem like this once.

That's good hack!

I personally prefer Ellipsis. Its meaning make more sense to me (it Greek origin mean "omission") i.e. "Not Set" so it almost perfectly matches.

Re: Notset: A Do-Not-Care value for Python

#35

The sentinel value you've used here is the right solution. It keeps the keyword arguments explicit and gives None its value back. However, it doesn't deserve a module global-to-python to live in. The cases where you use this pattern are broader than just "NotSet". Good pattern, and it needs to be more widely-known, but it doesn't need to occupy the space of a module on PyPI. ;-)

I'd love to see this integrated into the language and live along side of `None` (I can dream, can't I?) But until then, how can two different libraries agree to use the exact same instance of `NotSet` without some standard package defining it? The goal is really to be able to 'proxy' this do-not-care condition from applications into libraries in a standardized way.

I'll repeat my advice to take this to the python-ideas mailing list. You'll get real reasons why this shouldn't (or should) be included in __builtins__.

As far as two libraries agreeing on using the same instance, one can define it the way you've done with `NotSet = object()`, and they can both use it just like they share any other named object (classes, functions, constants, sentinels). Better yet, it can carry a more meaningful name when "NotSet" doesn't really describe how they're using the sentinel.

Re: Notset: A Do-Not-Care value for Python

#36
post #22

The kwargs form is a more obvious API. When your users grow more fields -- email, registration date, avatar -- this code will be reusable, whereas a function with a signature will need its arguments changed whenever the database schema changes. The three-valued logic of set-to-something, set-to-None, don't-set is perfectly adequately captured by a dictionary. You're introducing an application-specific concept (the No…

> whereas a function with a signature will need its arguments changed whenever the database schema changes. True there is some work in keeping the two synchronized, but there are benefits. First, unexpected arguments are immediately caught since they throw a TypeError. Without this, you either have to manually check for unexpected keys (probably doing a set difference with `allowed_keys` or something) or you just sil…

> First, unexpected arguments are immediately caught since they throw a TypeError.

> Without this, you either have to manually check for unexpected keys (probably doing a set difference with `allowed_keys` or something) or you just silently pass through unrecognized attributes, probably causing strange behavior later on.

The default constructor for SQLAlchemy declarative base does a simple check for unexpected keys, and it has served me well:

https://bitbucket.org/sqlalchemy/sqlalchemy/src/acbaeb1acb7d...

> Second, you are forced to say explicitly which attributes are modifiable. To draw from the 'person' example, `name` and `age` might be modifiable, but `admin` might be protected. That would be made abundantly clear by `update(person, name=NotSet, age=NotSet)`, but less so, by `update(person, attrs)` or `update(person, kwargs)`.

Whether a field is modifiable is often determined by the current user's access level and the current state of the object. So, putting such restriction at the function definition may have made things too rigid.

Re: Notset: A Do-Not-Care value for Python

#37
post #36

Earlier quoted context omitted.

> whereas a function with a signature will need its arguments changed whenever the database schema changes. True there is some work in keeping the two synchronized, but there are benefits. First, unexpected arguments are immediately caught since they throw a TypeError. Without this, you either have to manually check for unexpected keys (probably doing a set difference with `allowed_keys` or something) or you just sil…

> First, unexpected arguments are immediately caught since they throw a TypeError. > Without this, you either have to manually check for unexpected keys (probably doing a set difference with `allowed_keys` or something) or you just silently pass through unrecognized attributes, probably causing strange behavior later on. The default constructor for SQLAlchemy declarative base does a simple check for unexpected keys,…

> Whether a field is modifiable is often determined by the current user's access level and the current state of the object. So, putting such restriction at the function definition may have made things too rigid.

True, let me try to clarify. There might be some attributes like `admin` that you don't want twiddled via the `update` method but rather mutated via a setter function. In this case, the signature of the `update` function would be helping to indicate that.

(A better example might be the attribute `active` with two methods called `activate` and `deactivate` that send emails and what-not.)

Re: Notset: A Do-Not-Care value for Python

#38

My first impression is that this isn't a problem in need of solving; it just needs a change in approach. The first is the conflation of classes and functions that work with classes. The update function in the example isn't reusable at all, implies you can update something other than a Person, and 'NotSet' doesn't fix that. So have it as a method on Person, and pass in a list of attributes to change as opposed to enum…

Their is no way to tell that the example function is not a method of a Person class.

The code: "def update(person, name=None, age=None):"

is equivelent to the code: "def update(self, name=None, age=None):"

although if you chose to name the 'self' variable something other than 'self', you probably deserve to have problems.

Re: Notset: A Do-Not-Care value for Python

#39

My first impression is that this isn't a problem in need of solving; it just needs a change in approach. The first is the conflation of classes and functions that work with classes. The update function in the example isn't reusable at all, implies you can update something other than a Person, and 'NotSet' doesn't fix that. So have it as a method on Person, and pass in a list of attributes to change as opposed to enum…

Their is no way to tell that the example function is not a method of a Person class. The code: "def update(person, name=None, age=None):" is equivelent to the code: "def update(self, name=None, age=None):" although if you chose to name the 'self' variable something other than 'self', you probably deserve to have problems.

Agreed, I think the distinction between a bound method or a function is irrelevant here.

If we want explicit kwargs (a big 'if' since many of the suggestions in this thread are to give up on that idea), then we need some value to distinguish it from None.

Re: Notset: A Do-Not-Care value for Python

#40
post #24

This is one of the features of Scala I like; explicit types for Option/Some/None in the core language and standard API. It's generally used for return types (ex: a hashmap 'get' will have a return type of Option[ValueType] and return either Some[ValueType] or None) but you can use it for function parameters as well. scala> def foo(name:Option[String] = None, age:Option[Int] = None) = { | println("==========") | if( n…

Yeah, not sure why there is so much confusion in pythonland over an issue that has a trivial solution that was discovered ages ago, moments after the problem first appeared.
Post reply on HN