Is everything an object in Python like Ruby? - python

I read on another Stack Overflow question that Python was just like Ruby, as it relates to "everything's an object," and everything in Python was an object, just like Ruby.
Is this true? Is everything an object in Python like Ruby?
How are the two different in this respect or are they really the same? For example, can you take a number and do the Ruby stuff I've seen like:
y = 5.plus 6
Can that be done the same way in Python?

DiveIntoPython - Everything Is an Object
Everything in Python is an object, and almost everything has attributes and methods. All functions have a built-in attribute __doc__, which returns the doc string defined in the function's source code. The sys module is an object which has (among other things) an attribute called path. And so forth.
Still, this begs the question. What is an object? Different programming languages define “object” in different ways. In some, it means that all objects must have attributes and methods; in others, it means that all objects are subclassable. In Python, the definition is looser; some objects have neither attributes nor methods (more on this in Chapter 3), and not all objects are subclassable (more on this in Chapter 5). But everything is an object in the sense that it can be assigned to a variable or passed as an argument to a function (more in this in Chapter 4).
Ruby Docs - To Ruby From Python
As with Python, in Ruby,... Everything is an object
So there you have it from Ruby's own website: in Python everything is an object.

While everything is an object in Python, it differs from Ruby in its approach to resolving names and interacting with objects.
For example, while Ruby provides you with a 'to_s' method on the Object base class, in order to expose that functionality, Python integrates it into the string type itself - you convert a type to a string by constructing a string from it. Instead of 5.to_s, you have str(5).
Don't be fooled, though. There's still a method behind the scenes - which is why this code works:
(5).__str__()
So in practice, the two are fundamentally similar, but you use them differently. Length for sequences like lists and tuples in Python is another example of this principle at work - the actual feature is built upon methods with special names, but exposed through a simpler, easier-to-use interface (the len function).
The Python equivalent to what you wrote in your question would thus be:
(5).__add__(6)
The other difference that's important is how global functions are implemented. In Python, globals are represented by a dictionary (as are locals). This means that the following:
foo(5)
Is equivalent to this in Python:
globals()["foo"].__call__(5)
While Ruby effectively does this:
Object.foo(5)
This has a large impact on the approach used when writing code in both languages. Ruby libraries tend to grow through the addition of methods to existing types like Object, while Python libraries tend to grow through the addition of global functions to a given module.

"everything" is a tad of an overbid, for both Python and Ruby -- for example, if is not "an object", rather it's a keyword used to start a conditional statement or (in Python) inside list comprehensions and generator expressions. The enthusiasm of finding out that functions, classes, methods, and all sort of such things that aren't really objects in (say) C++, are objects in Ruby or Python, causes such enthusiasm. Other things may be objects in Ruby but not Python or viceversa (code blocks, regular expressions, ...).

In answer to your second question, yes:
>>> (1).__add__(2)
3

Yep, as far as I know everything is an object in Python. Certainly the primitive and builtin types (int, long, str, float, etc.) can be subclassed - and in fact the types themselves are objects. Functions are objects, classes are objects, even code blocks are objects in a sense... I can't think of anything in Python that can't be treated as an object.

To add a comment to other people's excellent answers: everything is an object, but some – notably strings and numeric types – are immutable. This means that these types behave the way they do in languages like C or Java (where integers, etc. are not objects) with respect to assignment, parameter passing, etc, and you never have to worry about traps caused by pass-by-reference. It's rather a good solution :-)

Hello and answer is out of the bat not everything, reference is more complete than that and offers many more avenues, within Python 3.8.5 for example Delimiters, Operators and Keywords are not objects. stackoverflow.com/a/66374328/11554034
Have explained it with some detail in that link feel free to check it along.
Anyway, next one says that statement you can correct it by saying (something more correct, although if still can be more completed feel free):
"Everything in a logical line that is not NEWLINE, INDENT, DEDENT, Space bar Character, Operator, Keyword or Delimiter is an object in Python."
Cheers.

Yes, everything is object in Python as long as I researched.
The documentation says below:
Objects are Python’s abstraction for data. All data in a Python
program is represented by objects or by relations between objects.
Every object has an identity, a type and a value.
And, I also checked the type of each value and if each of them is the instance of a particular class as shown below:
from types import FunctionType
class Person:
pass
def test():
pass
print(type("Hello"), isinstance("Hello", str))
print(type(100), isinstance(100, int))
print(type(100.23), isinstance(100.23, float))
print(type(100 + 2j), isinstance(100 + 2j, complex))
print(type(True), isinstance(True, bool))
print(type(None), isinstance(None, type(None)))
print(type([]), isinstance([], list))
print(type(()), isinstance((), tuple))
print(type({}), isinstance({}, dict))
print(type({""}), isinstance({""}, set))
print(type(Person), isinstance(Person, type))
print(type(test), isinstance(test, FunctionType))
Output:
<class 'str'> True
<class 'int'> True
<class 'float'> True
<class 'complex'> True
<class 'bool'> True
<class 'NoneType'> True
<class 'list'> True
<class 'tuple'> True
<class 'dict'> True
<class 'set'> True
<class 'type'> True
<class 'function'> True

Related

Is type a 'builtin-function' or 'class' in python

I'm looking at the python documentation and came across 'type()' under the built-in-functions section. https://docs.python.org/3/library/functions.html
However, when I look at the actual details, I see it as a class which takes 1 or 3 arguments. https://docs.python.org/3/library/functions.html#type
>>> type(type)
<class 'type'>
>>> type(pow)
<class 'builtin_function_or_method'>
If it's not a function, why is it listed under builtin-functions section.? Am I missing something.?
Python has a number of objects that are callable. Some are used more like functions, even though they are actually classes or types. The distinction isn't really that important, more of an implementation detail.
For example, list() gives you a new list. That's because list is a type. But if you want to think of it as a function that makes lists, that's OK too.

Difference of type() function in Python 2 and Python 3

When trying the following script in Python 2,
a = 200
print type(a)
its output is
<type 'int'>
and in Python 3, the script
a = 200
print (type(a))
its output is,
<class 'int'>
What may be the reason for that?
In the days of yore, built-in types such as int and dict and list were very different from types built with class. You could not subclass built-in types for example.
Gradually, in successive Python 2.x releases, the differences between class types and builtin types have eroded; the introduction of new-style classes (inheriting from object) in Python 2.2 was one such (major) step. See Unifying types and classes in Python 2.2.
Removing the use of type in built-in type representations is just the last step in that process. There was no reason anymore to use the name type anymore.
In other words, between Python 2.7 and 3.x this is a cosmetic change, nothing more.
type isn't behaving any differently. They just changed things so all classes show up as <class ...> instead of <type ...>, regardless of whether the class is a built-in type like int or a class created with the class statement. It's one of the final steps of the elimination of the class/type distinction, a process that began back in 2.2.

Class vs. Type in Python

I just recently started to teach myself how to code. I am currently reading Think Python 2 for python 3 and when it teaches about the type() function, it gives the example type(2) which outputs <class 'int'>. It then states that "the word 'class' is used in the sense of a category; a type is a category of values."
The part that confuses me is that the type() function outputs class instead of type. Also, I'm not sure about the difference between type and class; are string, float point, and integer classes of the type "value", or are they the same thing?
I have looked this up but cannot find an answer to my specific questions or simple enough for me to understand.
Once upon a time, Python had both types and classes. Types were built-in objects defined in C; classes were what you built when using a class statement. The two were named differently because you couldn't mix these; classes could not extend types.
This difference was artificial, a limitation in the language implementation. Starting with Python 2.2, the developers of Python have slowly moved towards unifying the two concepts, with the difference all but gone in Python 3. Built-in types are now also labelled classes, and you can extend them at will.
Your book is trying to explain a difference that isn't present in Python anymore. Even in Python 2 the difference is only there in name, since type(2) shows the word 'type' is still used there:
>>> type(2)
<type 'int'>
but you can subclass int just like any other class.
(Python 2 does still have old-style classes, those that don't inherit from object; these are a remnant of the old system from before the unification.)
The python hierarchy is Type (Metaclass) -> Class -> Instance.
Think of the function type() as going one level up.
If you use the function type() on an instance of an int (any integer) like so: type(123) you will receive the class of the instance which in this case is int. If you will use type() on the class int, you will recieve type type which is the metaclass of int.
Keep in mind metaclasses are advanced technical details of python and you do not need to learn about them at first.

What does "Everything" mean when someone says "Everything in Python is an object."?

I constantly see people state that "Everything in Python is an object.", but I haven't seen "thing" actually defined. This saying would lead me to believe that all tokens of any kind are also considered to be objects, including operators, punctuators, whitespace, etc. Is that actually the case? Is there a more concise way of stating what a Python object actually is?
Thanks
Anything that can be assigned to a variable is an object.
That includes functions, classes, and modules, and of course int's, str's, float's, list's, and everything else. It does not include whitespace, punctuation, or operators.
Just to mention it, there is the operator module in the standard library which includes functions that implement operators; those functions are objects. That doesn't mean + or * are objects.
I could go on and on, but this is simple and pretty complete.
Some values are obviously objects; they are instances of a class, have attributes, etc.
>>> i = 3
>>> type(i)
<type 'int'>
>>> i.denominator
1
Other values are less obviously objects. Types are objects:
>>> type(int)
<type 'type'>
>>> int.__mul__(3, 5)
15
Even type is an object (of type type, oddly enough):
>>> type(type)
<type 'type'>
Modules are objects:
>>> import sys
>>> type(sys)
<type 'module'>
Built-in functions are objects:
>>> type(sum)
<type 'builtin_function_or_method'>
In short, if you can reference it by name, it's an object.
What is generally meant is that most things, for example functions and methods are objects. Modules too. Classes (not just their instances) themselves are objects. and int/float/strings are objects. So, yes, things generally tend to be objects in Python. Cyphase is correct, I just wanted to give some examples of things that might not be immediately obvious as objects.
Being objects then a number of properties are observable on things that you would consider special case, baked-in stuff in other languages. Though __dict__, which allows arbitrary attribute assignment in Python, is often missing on things intended for large volume instantiations like int.
Therefore, at least on pure-Python objects, a lot of magic can happen, from introspection to things like creating a new class on the fly.
Kinda like turtles all the way down.
You're not going to find a rigorous definition like C++11's, because Python does not have a formal specification like C++11, it has a reference manual like pre-ISO C++. The Data model chapter is as rigorous as it gets:
Objects are Python’s abstraction for data. All data in a Python program is represented by objects or by relations between objects. (In a sense, and in conformance to Von Neumann’s model of a “stored program computer,” code is also represented by objects.)
Every object has an identity, a type and a value. An object’s identity never changes once it has been created; you may think of it as the object’s address in memory. …
The glossary also has a shorter definition:
Any data with state (attributes or value) and defined behavior (methods).
And it's true that everything in Python has methods and (other) attributes. Even if there are no public methods, there's a set of special methods and values inherited from the object base class, like the __str__ method.
This wasn't true in versions of Python before 2.2, which is part of the reason we have multiple words for nearly the same thing—object, data, value; type, class… But from then on, the following kinds of things are identical:
Objects.
Things that can be returned or yielded by a function.
Things that can be stored in a variable (including a parameter).
Things that are instances of type object (usually indirectly, through a subclass or two).
Things that can be the value resulting from an expression.
Things represented by pointers to PyObject structs in CPython.
… and so on.
That's what "everything is an object" means.
It also means that Python doesn't have "native types" and "class types" like Java, or "value types" and "reference types" like C#; there's only one kind of thing, objects.
This saying would lead me to believe that all tokens of any kind are also considered to be objects, including operators, punctuators, whitespace, etc. Is that actually the case?
No. Those things don't have values, so they're not objects.1
Also, variables are not objects. Unlike C-style variables, Python variables are not memory locations with a type containing a value, they're just names bound to a value in some namespace.2 And that's why you can't pass around references to variables; there is no "thing" to reference.3
Assignment targets are also not objects. They sometimes look a lot like values, and even the core devs sometimes refer to things like the a, b in a, b = 1, 2 loosely as a tuple object—but there is no tuple there.4
There's also a bit of apparent vagueness with things like elements of a numpy.array (or an array.array or ctypes.Structure). When you write a[0] = 3, the 3 object doesn't get stored in the array the way it would with a list. Instead, numpy stores some bytes that Python doesn't even understand, but that it can use to do "the same thing a 3 would do" in array-wide operations, or to make a new copy of the 3 object if you later ask for a[0] = 3.
But if you go back to the definition, it's pretty clear that this "virtual 3" is not an object—while it has a type and value, it does not have an identity.
1. At the meta level, you can write an import hook that can act on imported code as a byte string, a decoded Unicode string, a list of token tuples, an AST node, a code object, or a module, and all of those are objects… But at the "normal" level, from within the code being imported, tokens, etc. are not objects.
2. Under the covers, there's almost always a string object to represent that name, stored in a dict or tuple that represents the namespace, as you can see by calling globals() or dir(self). But that's not what the variable is.
3. A closure cell is sort of a way of representing a reference to a variable, but really, it's the cell itself that's an object, and the variables at different scopes are just a slightly special kind of name for that cell.
4. However, in a[0] = 3, although a[0] isn't a value, a and 0 are, because that assignment is equivalent to the expression a.__setitem__(0, 3), except that it's not an expression.

When is the output of repr useful?

I have been reading about repr in Python. I was wondering what the application of the output of repr is. e.g.
class A:
pass
repr(A) ='<class __main__.A at 0x6f570>'
b=A()
repr(b) = '<__main__.A instance at 0x74d78>'
When would one be interested in '<class __main__.A at 0x6f570>' or'<__main__.A instance at 0x74d78>'?
Theoretically, repr(obj) should spit out a string such that it can be fed into eval to recreate the object. In other words,
obj2 = eval(repr(obj1))
should reproduce the object.
In practice, repr is often a "lite" version of str. str might print a human-readable form of the object, whereas repr prints out information like the object's class, usually for debugging purposes. But the usefulness depends a lot on your situation and how the object in question handles repr.
Sometimes you have to deal with or present a byte string such as
bob2='bob\xf0\xa4\xad\xa2'
If you print this out (in Ubuntu) you get
In [62]: print(bob2)
bob𤭢
which is not very helpful to others trying to understand your byte string. In the comments, John points out that in Windows, print(bob2) results in something like bob𤭢. The problem is that Python detects the default encoding of your terminal/console and tries to decode the byte string according to that encoding. Since Ubuntu and Windows uses different default encodings (possibly utf-8 and cp1252 respectively), different results ensue.
In contrast, the repr of a string is unambiguous:
In [63]: print(repr(bob2))
'bob\xf0\xa4\xad\xa2'
When people post questions here on SO about Python strings, they are often asked to show the repr of the string so we know for sure what string they are dealing with.
In general, the repr should be an unambiguous string representation of the object. repr(obj) calls the object obj's __repr__ method. Since in your example the class A does not have its own __repr__ method, repr(b) resorts to indicating the class and memory address.
You can override the __repr__ method to give more relevant information.
In your example, '<__main__.A instance at 0x74d78>' tells us two useful things:
that b is an instance of class A
in the __main__
namespace,
and that the object resides in
memory at address 0x74d78.
You might for instance, have two instances of class A. If they have the same memory address then you'd know they are "pointing" to the same underlying object. (Note this information can also be obtained using id).
The main purpose of repr() is that it is used in the interactive interpreter and in the debugger to format objects in human-readable form. The example you gave is mainly useful for debugging purposes.

Categories

Resources