6

For example, when I have such a Node class defined.

class Node:
    def __init__(self, val=None, next=None):
        self.val = val
        self.next = next

    def __bool__(self):
        return self.val is not None

When I initialize it with empty arguments, like below. Is there a way to self-define method to say a is None?

a = Node()
a is None # False, but can it be true if I want?
6
  • 5
    No, a class instance can't be None. Commented May 14, 2020 at 20:15
  • 1
    This would break lots of things, because you'd get errors when you try to call class methods. Commented May 14, 2020 at 20:16
  • You'd have to check for None before every method call. Commented May 14, 2020 at 20:17
  • The __bool__ method will allow you to write if a: and if not a: Commented May 14, 2020 at 20:17
  • 3
    What do you hope to accomplish this way? Why not just actually use None in the places where you want is None to be true? What actually is a Node, and what are you planning to do with these Nodes? Commented May 14, 2020 at 20:37

4 Answers 4

5

While you cannot override the is comparison, you can at least override the equality operator if you want to quickly check up whether a specific parameter (or condition) within your class should yield True on comparison, e.g.:

class Node:
    def __init__(self, val=None, next=None):
        self.val = val
        self.next = next

    def __eq__(self, obj):
        return obj == self.val

n = Node()
print(n == None)  # True
n = Node(5)
print(n == None)  # False
Sign up to request clarification or add additional context in comments.

1 Comment

Nice. Thanks for sharing about this eq method. works as well as bool method.
4

No, but...

You cannot override the is, and, or or operators.

Defining __bool__ allows you to write statements like

class Node:
    def __init__(self, val):
        self.val = val

    def __bool__(self):
        return self.val is not None   # <--- added "return"

for val in (0, 1, True, None):
    n = Node(val)
    # These three are equivalent
    if n:
        assert n.__bool__()
        assert n.val is not None
    # These three are equivalent
    else:
        assert not n.__bool__()
        assert n.val is None

https://docs.python.org/3/reference/datamodel.html#object.bool

6 Comments

He did define __bool__.
True, clarified answer
@Barmar: Note the OP didn't define __bool__() to return anything.
Cireo: There's no variable named x. Also, don't use n.__bool__(), use bool(n), or even more simply: assert n.
I'm not suggesting he (or anyone) writes code using __bool__(), that is for pedagogical purposes
|
2

This may not do exactly what you want but you could overwrite the __new__ class method so that, when the class constructor is called with no arguments, the None object is returned instead of an instance of Node.

I think this should work (my metaclass knowledge is spotty).

class Node:
    def __new__(cls, val=None, next=None):
        if val is None and next is None:
            return None

        return super().__init__(cls, val, next)

    def __init__(self, val, next):
        if self is None:
            return

        ...

It is my duty to recommend that you not go down this route, however. Fiddling with __new__ is tricky and dangerous and is probably more trouble than it's worth.

7 Comments

Oh, really? Thanks. Told you my metaclass knowledge was spotty.
There is no metaclass here... __new__ is actually just a constructor, (__init__ is technically an initializer). A metaclass is the class of a class. All classes are merely instances of type. You can inherit from type to create a metaclass, but that isn't what you need here. What you've shown here is correct, although, as you already say, probably not the best route. I think the OP probably just needs something else. Once your constructor starts returning objects not of the same type you've created a problem, IMO...
@juanpa: IMO it's fine to use @classmethod on __new__() even if it's not necessary — "Explicit is better than implicit" in Python.
Daniel: One potential problem: isinstance(Node(), Node)False.
@martineau I don't want to extend the rabbit hole too far, but you could define a metaclass (for real this time) and define __instancecheck__ to say that None was an instance.... <here be dragons>
|
0

You should initialize the class variable as a parameter. Try below code lines.

class dummy(object):
     empty_array = []
     def __init__(self, size):
        self.empty_array = [[None]*2 for i in range(size)]

a = dummy(3)
print (a.empty_array)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.