Re: Disallowing instantiation of super class
> On Feb 24, 2017, at 1:24 AM, Steve D'Aprano > wrote: > > On Fri, 24 Feb 2017 11:19 am, Irv Kalb wrote: > >> Hi, >> >> I have built a set of three classes: >> >> - A super class, let's call it: Base > [...] >> I would like to add is some "insurance" that I (or someone else who uses >> my code) never instantiates my Base class, It is not intended to be >> instantiated because some of the needed instance variables are only >> created in the __init__ method of ClassA and ClassB. > > class Base: > def __init__(self): > if type(self) is Base: > raise TypeError("cannot instantiate Base class") > > > Does that help? > > Double D'oh!! That's exactly what I was looking for. (Why didn't I think of that?) Thanks very much! Irv -- https://mail.python.org/mailman/listinfo/python-list
Re: Disallowing instantiation of super class
On Sat, 25 Feb 2017 05:40 am, MRAB wrote: >> class Base: >> def __init__(self): >> if type(self) is Base: >> raise TypeError("cannot instantiate Base class") >> >> >> Does that help? >> > D'oh! Never thought of that! :-) > > The OP is using Python 2.7, so you'll need to use new-style classes: > > class Base(object): > def __init__(self): > if type(self) is Base: > raise TypeError("cannot instantiate Base class") For "classic classes", you can use this: if self.__class__ is Base: raise TypeError("cannot instantiate Base class") -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Disallowing instantiation of super class
On 2017-02-24 09:24, Steve D'Aprano wrote: On Fri, 24 Feb 2017 11:19 am, Irv Kalb wrote: Hi, I have built a set of three classes: - A super class, let's call it: Base [...] I would like to add is some "insurance" that I (or someone else who uses my code) never instantiates my Base class, It is not intended to be instantiated because some of the needed instance variables are only created in the __init__ method of ClassA and ClassB. class Base: def __init__(self): if type(self) is Base: raise TypeError("cannot instantiate Base class") Does that help? D'oh! Never thought of that! :-) The OP is using Python 2.7, so you'll need to use new-style classes: class Base(object): def __init__(self): if type(self) is Base: raise TypeError("cannot instantiate Base class") -- https://mail.python.org/mailman/listinfo/python-list
Re: Disallowing instantiation of super class
On 24.02.2017 01:19, Irv Kalb wrote: Hi, I have built a set of three classes: - A super class, let's call it: Base - A class that inherits from Base, let's call that: ClassA - Another class that inherits from Base, let's call that: ClassB ClassA and ClassB have some code in their __init__ methods that set some instance variables to different values. After doing so, they call the the __init__ method of their common super class (Base) to set some other instance variables to some common values. This all works great. Instances of ClassA and ClassB do just what I want them to. [...] If I can find a way to determine that the caller is attempting to instantiate Base directly, I will raise an exception. A pattern I'm using sometimes to achieve this is: class Base: def __init__(self): self.set_common() self.set_specific() def set_common(self): self.a = 10 def set_specific(self): raise NotImplementedError() class A(Base): def set_specific(self): self.b = 20 class B(Base): def set_specific(self): self.b = 30 Of course, MRAB's and Peter's suggestion are very similar ideas. -- https://mail.python.org/mailman/listinfo/python-list
Re: Disallowing instantiation of super class
On Fri, 24 Feb 2017 11:19 am, Irv Kalb wrote: > Hi, > > I have built a set of three classes: > > - A super class, let's call it: Base [...] > I would like to add is some "insurance" that I (or someone else who uses > my code) never instantiates my Base class, It is not intended to be > instantiated because some of the needed instance variables are only > created in the __init__ method of ClassA and ClassB. class Base: def __init__(self): if type(self) is Base: raise TypeError("cannot instantiate Base class") Does that help? -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Disallowing instantiation of super class
> On Feb 23, 2017, at 4:40 PM, MRAB wrote: > > On 2017-02-24 00:19, Irv Kalb wrote: >> Hi, >> >> I have built a set of three classes: >> >> - A super class, let's call it: Base >> >> - A class that inherits from Base, let's call that: ClassA >> >> - Another class that inherits from Base, let's call that: ClassB >> >> ClassA and ClassB have some code in their __init__ methods that set some >> instance variables to different values. After doing so, they call the the >> __init__ method of their common super class (Base) to set some other >> instance variables to some common values. This all works great. Instances >> of ClassA and ClassB do just what I want them to. >> >> I would like to add is some "insurance" that I (or someone else who uses my >> code) never instantiates my Base class, It is not intended to be >> instantiated because some of the needed instance variables are only created >> in the __init__ method of ClassA and ClassB. I am looking for some way in >> the Base's __init__ method to determine if the method was called directly: >> >>instanceOfBase = Base(... some data ...) # I want this case to generate >> an error >> >> I tried using "isinstance(self, Base)", but it returns True when I >> instantiate an object from ClassA, from ClassB, or from Base. >> >> If I can find a way to determine that the caller is attempting to >> instantiate Base directly, I will raise an exception. >> >> Thanks, >> >> Irv >> >> (If it makes a difference, I am doing this currently in Python 2.7 - please >> don't beat me up about that.) >> > Apart from renaming Base to _Base as a hint, you could put Base's > initialisation code in, say, '_init' and have Base's __init__ just raise an > exception. > > ClassA and ClassB would then call Base's _init instead of its __init__. > > -- > https://mail.python.org/mailman/listinfo/python-list > MRAB and Peter: Thank you very much for your solutions. I had considered both of these, but was wondering if there was another way. Peter's solution does exactly what I want, but I'm not ready to get into metaclasses. So I decided to go with MRAB's approach. I've modified my code and it seems to work great. Thank you both. Irv -- https://mail.python.org/mailman/listinfo/python-list
Re: Disallowing instantiation of super class
Irv Kalb wrote: > Hi, > > I have built a set of three classes: > > - A super class, let's call it: Base > > - A class that inherits from Base, let's call that: ClassA > > - Another class that inherits from Base, let's call that: ClassB > > ClassA and ClassB have some code in their __init__ methods that set some > instance variables to different values. After doing so, they call the the > __init__ method of their common super class (Base) to set some other > instance variables to some common values. This all works great. > Instances of ClassA and ClassB do just what I want them to. > > I would like to add is some "insurance" that I (or someone else who uses > my code) never instantiates my Base class, It is not intended to be > instantiated because some of the needed instance variables are only > created in the __init__ method of ClassA and ClassB. I am looking for > some way in the Base's __init__ method to determine if the method was > called directly: > > instanceOfBase = Base(... some data ...) # I want this case to > generate an error > > I tried using "isinstance(self, Base)", but it returns True when I > instantiate an object from ClassA, from ClassB, or from Base. > > If I can find a way to determine that the caller is attempting to > instantiate Base directly, I will raise an exception. > > Thanks, > > Irv > > (If it makes a difference, I am doing this currently in Python 2.7 - > please don't beat me up about that.) >>> import abc >>> class Base: ... __metaclass__ = abc.ABCMeta ... @abc.abstractmethod ... def __init__(self): ... self.z = self.x + self.y ... >>> class A(Base): ... def __init__(self): ... self.x = 2 ... self.y = 3 ... super(A, self).__init__() ... >>> A().z 5 >>> Base() Traceback (most recent call last): File "", line 1, in TypeError: Can't instantiate abstract class Base with abstract methods __init__ -- https://mail.python.org/mailman/listinfo/python-list
Re: Disallowing instantiation of super class
On 2017-02-24 00:19, Irv Kalb wrote: Hi, I have built a set of three classes: - A super class, let's call it: Base - A class that inherits from Base, let's call that: ClassA - Another class that inherits from Base, let's call that: ClassB ClassA and ClassB have some code in their __init__ methods that set some instance variables to different values. After doing so, they call the the __init__ method of their common super class (Base) to set some other instance variables to some common values. This all works great. Instances of ClassA and ClassB do just what I want them to. I would like to add is some "insurance" that I (or someone else who uses my code) never instantiates my Base class, It is not intended to be instantiated because some of the needed instance variables are only created in the __init__ method of ClassA and ClassB. I am looking for some way in the Base's __init__ method to determine if the method was called directly: instanceOfBase = Base(... some data ...) # I want this case to generate an error I tried using "isinstance(self, Base)", but it returns True when I instantiate an object from ClassA, from ClassB, or from Base. If I can find a way to determine that the caller is attempting to instantiate Base directly, I will raise an exception. Thanks, Irv (If it makes a difference, I am doing this currently in Python 2.7 - please don't beat me up about that.) Apart from renaming Base to _Base as a hint, you could put Base's initialisation code in, say, '_init' and have Base's __init__ just raise an exception. ClassA and ClassB would then call Base's _init instead of its __init__. -- https://mail.python.org/mailman/listinfo/python-list
Disallowing instantiation of super class
Hi, I have built a set of three classes: - A super class, let's call it: Base - A class that inherits from Base, let's call that: ClassA - Another class that inherits from Base, let's call that: ClassB ClassA and ClassB have some code in their __init__ methods that set some instance variables to different values. After doing so, they call the the __init__ method of their common super class (Base) to set some other instance variables to some common values. This all works great. Instances of ClassA and ClassB do just what I want them to. I would like to add is some "insurance" that I (or someone else who uses my code) never instantiates my Base class, It is not intended to be instantiated because some of the needed instance variables are only created in the __init__ method of ClassA and ClassB. I am looking for some way in the Base's __init__ method to determine if the method was called directly: instanceOfBase = Base(... some data ...) # I want this case to generate an error I tried using "isinstance(self, Base)", but it returns True when I instantiate an object from ClassA, from ClassB, or from Base. If I can find a way to determine that the caller is attempting to instantiate Base directly, I will raise an exception. Thanks, Irv (If it makes a difference, I am doing this currently in Python 2.7 - please don't beat me up about that.) -- https://mail.python.org/mailman/listinfo/python-list