On 03/25/2018 04:31 PM, Ian Kelly wrote:
On Sun, Mar 25, 2018 at 9:01 AM, Jugurtha Hadjar
<jugurtha.had...@gmail.com> wrote:
On 03/25/2018 03:25 PM, Terry Reedy wrote:
None.foo will raise AttributeError.

Right.. As I said, I tried to assume as little as possible about OP's code
and namespace. Didn't want to include C1 in __init__ signature because I
wasn't sure it was available in the namespace.

It is easy to address, though:

Example A:

class C2(object):
      def __init__(self, parent=C2):
          self.parent = parent
This doesn't work as written (try it!)

Sorry, I was writing on a my commute and made a mistake. I meant parent=C1.

Furthermore, having a positional argument will not save us. We can still
break the code if we do the following:

class C2(object):
     def __init__(self, parent):
         self.parent = parent
     def foo(self):
         self.parent.foo()

c1 = C1()
c2 = C2(None)
c2.foo()

Making it positional didn't fix our wickedness.
The difference is that in this case the fault is on the caller for
passing a nonsense value. In the original the fault is on the class
author for providing a useless default and implying that the argument
is not required.

The point about the default can be found in my previous answer: If it's my code and I know the object I want to use as a default lives in the module, I'll provide it as a default parameter, but we're talking about C1 and C2 in an abstract way and I chose to make the fewest assumptions possibles (maybe too few) OP's code, which may have made the keyword argument/positional argument/optional argument/None bubble up. My main point in my original reply: I much prefer restricting as little as possible and delaying instantiation as much as possible which has helped me a lot, especially with testing (for when I don't have access to a device represented by the class, or trying to test offline), making the library usage easier for myself and others, and avoiding a lot of problems down-range (for instance, hot swapping a hardware connection after class instantiation is easier when code it's written that way as opposed to have it as a required argument). There sure is scar tissue and it may not be to everyone's taste, but it has served me well.

Again, I do provide defaults when it's code I write, but I can't guess what the original code does so I may have fell into muscle memory.



--
~ Jugurtha Hadjar,

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to