How Is the 'Is' Keyword Implemented in Python

How is the 'is' keyword implemented in Python?

Testing strings with is only works when the strings are interned. Unless you really know what you're doing and explicitly interned the strings you should never use is on strings.

is tests for identity, not equality. That means Python simply compares the memory address a object resides in. is basically answers the question "Do I have two names for the same object?" - overloading that would make no sense.

For example, ("a" * 100) is ("a" * 100) is False. Usually Python writes each string into a different memory location, interning mostly happens for string literals.

Does Python's `in` keyword perform a linear search?

Python's in operator calls the __contains__ magic function on the container. That is implemented in different ways for different containers.

For strings, lists and tuples, it's a linear search (O(N)), though since it's implemented in C it will probably be faster than the pure-python one you have in your question.

For a sets and dicts, it's a hash-table lookup, which is much faster (O(1) average case).

Other containers will have different performance characteristics. I don't think there are any in the standard library, but a balanced tree data structure would probably be O(log N).

Behaviour of is keyword in python?

The is keyword in python is used to test if two variables refer to the same object. It returns True if the two variable are referring to same object otherwise it returns False.

For Example consider the class named A:

class A:
pass

Case 1:

x = A() #--> create instance of class A
y = A() #--> create instance of class A

>>> x is y
>>> False

Case 2:

x = A() #--> create instance of class A
y = x #--> here y refers to the instance of x
>>> x is y
>>> True

Basically two variables refer to same object if they are referring to same memory location. You can check the identities of the variable by using the built in function in python called id(), this function returns the identity of the object (address of the object in memory).

  • In Case 1 id(x) is not equal to id(y) hence x is y returns
    False.
  • In Case 2 id(x) is equal to id(y) which implies both x and y refers to the same object inside the memory hence x is y returns
    True.

Now coming to your question,

def foo(el):
return (el is 0.0)

In the function foo el is 0.0 returns False because each of the two entities el and 0.0 refer to different locations inside memory. You can verify this fact by comparing id(el) == id(0.0) which returns False.

When, if ever, to use the 'is' keyword in Python?

You should use is when you want to know whether two objects are the same object. Don't use it when you want to know whether two objects have the same value.

There is a canonical example, but it is unfortunately not very helpful. People will tell you to always test for the None value using x is None instead of x == None. However, there is little practical difference between these cases. (See this question for explanation.)

In some situations, you may wind up creating objects which have the same value but are distinct objects. For instance, you could imagine creating a fantasy wargame in which the player can magically create minions to battle his opponent. So the player might create 100 identical orcs or whatever. Each orc could be represented by an object, and they would be identical in that they have the same properties, but still distinct in that there would be 100 separate objects. Now if the opponent tries to cast a "fireball" spell on one of these orcs, while on the same turn the player tries to cast "protect against fire" on an orc, you might want to check if the target of the fireball spell is the target of the protection spell. Equality wouldn't be enough, because all the orcs are equal, but only one particular orc is the target of each spell, and you want to know if the two targets are the same object. This is a rather contrived example, but should give a broad idea of the kind of situation where you might wind up using is.

Can I make my class play nice with the Python 'in keyword?

For iterating as in for x in object, you need to provide an __iter__ method which will return a new iterator.

An iterator is an object which has a method next() (Python 2) or __next__ (Python 3) which either returns the next element or raises StopIteration exception when there are no more elements. (An iterator should also have a method __iter__ that returns itself.)

Tip: You don't often need to code an iterator by yourself; the simplest way to implement __iter__ on a class is to make it a generator function or to return a generator expression from it (all generators are iterators). Also you can just return an iterator obtained from another object; the iter builtin is helpful here.


For testing if x in object, you need to provide a __contains__ method.

Further reading: Python data model - emulating container types

What is the python keyword with used for?

In python the with keyword is used when working with unmanaged resources (like file streams). It is similar to the using statement in VB.NET and C#. It allows you to ensure that a resource is "cleaned up" when the code that uses it finishes running, even if exceptions are thrown. It provides 'syntactic sugar' for try/finally blocks.

From Python Docs:

The with statement clarifies code that previously would use try...finally blocks to ensure that clean-up code is executed. In this section, I’ll discuss the statement as it will commonly be used. In the next section, I’ll examine the implementation details and show how to write objects for use with this statement.

The with statement is a control-flow structure whose basic structure is:

with expression [as variable]:
with-block

The expression is evaluated, and it should result in an object that supports the context management protocol (that is, has __enter__() and __exit__() methods).

Update fixed VB callout per Scott Wisniewski's comment. I was indeed confusing with with using.

The built-in keyword type means a function or a class in python?

type is called a "metaclass" because it's a class that produces other classes (AKA types). It behaves like a normal class. In particular, it has the equivalent of a __new__ method that would look something like this in Python:

class type(object):

def __new__(cls, *args):
num_args = len(args)

if num_args not in (1, 3):
raise TypeError('type() takes 1 or 3 arguments')

# type(x)
if num_args == 1:
return args[0].__class__

# type(name, bases, dict)
name, bases, attributes = args
bases = bases or (object,)

class Type(*bases):
pass

Type.__name__ = name

qualpath = Type.__qualname__.rsplit('.', 1)[0]
Type.__qualname__ = '.'.join((qualpath, name))

for name, value in attributes.items():
setattr(Type, name, value)

return Type

Class = type('Class', (), {'i': 1})
instance = Class()

print(type(instance)) # -> Class
print(instance.__class__) # -> Class
print(type(type(instance))) # -> type
print(Class.i) # -> 1
print(instance.i) # -> 1

Note that when instantiating a class, the value of the new instance is whatever is returned from __new__. In the case of type, __new__ always returns a type object (AKA class). Here's an example of a class that extends int to use -1 as the default value instead of 0:

def Int__new__(cls, *args):
if not args:
return cls(-1)
return super(cls, cls).__new__(cls, *args)

Int = type('Int', (int,), {'__new__': Int__new__})

i = Int()
print(type(i)) # -> Int
print(i.__class__) # -> Int
print(type(type(i))) # -> type
print(i) # -> -1

j = Int(1)
print(j) # -> 1

To really dig into how type works, take a look at the C code in type_new. You can see there (scroll down a few lines) that type(x) is a special case that immediately returns the type (AKA class) of x. When you do type(name, bases, dict), the type creation machinery is invoked.

For more fun, try the following:

type(object)
type(type)
isinstance(object, object)
isinstance(type, object)
type(1)
type(type(1))

Is 'input' a keyword in Python?

No, input is not a keyword. Instead, it is a built-in function.

And yes, you can create a variable with the name input. But please don't. Doing so is a bad practice because it overshadows the built-in (makes it unusable in the current scope).

If you must use the name input, the convention is to place an underscore after it:

input_ = input()


Related Topics



Leave a reply



Submit