osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Accessing parent objects



On 03/25/2018 04:31 PM, Ian Kelly wrote:
> On Sun, Mar 25, 2018 at 9:01 AM, Jugurtha Hadjar
> <jugurtha.hadjar at 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,