Difference in how functions are called in Python - python

I've noticed some functions are called using the var.func() format as in var1.split() while other functions are called using the func(var) format as in sorted(list1).
Here's a very simple program to illustrate the question. I've also noticed the same behavior with open and read functions.
str1 = "This is a string"
list1 = str1.split()
print str1.split(' ')
print sorted(list1)
I'm very new to programming so any help would be greatly appreciated!

Everything in python is an object. Thus when doing something like this:
s = "some string"
s is an str object and you can call all the str methods on it. You can also do things like this:
"some string".split()
and it will give you a list of splitted strings.

This difference has to do with issues of scope. Functions which can be called directly, such as sorted(list1) in your example above, are either builtin functions, or else defined at the top level of one of your imported libraries (for example when using from simpy import *, you can call test() directly to run the built in test suite for the simpy library). Functions which are accessed through the dot operator are functions which are defined for the particular data type that you are applying them to. Remember that each data type in python is an object, and therefore an instance of a class. Those functions, such as split() are defined in that data type's class definition. Additionally, to use the example of test() from the simpy library again, if you were to import a library with only import simpy, you would have to use simpy.test() to call that method.
from simpy import *
test()
vs
import simpy
simpy.test()
The first works because you've imported all methods and classes from the top level of the simpy library, whereas the second works because you've explicitly dived into the scope of the simpy library.

var.func() just means that the function belongs to the object.
For instance, x.sort(). lists (like x) have a function sort.
When you call func(var), func is not a function of lists.
For instance, sorted(x).
This isn't Python specific. You will see the same idea in other languages (e.g. Java).

In var.func() the func() is meant to be used with the var object.
e.g. split() on a string object but cannot use on a list
But func(var) is not confined to a single var object type. you can use it with any appropriate var object.
e.g. sorted() can be used with any iterable like lists, tuples, dicts...

Following TraxusIV's line of thought, I tried the following and it worked!
from string import split
str1 = "This is a string"
list1 = str1.split()
print split(str1)
print sorted(list1)

Related

Is it possible to access builtins or any other useful functions through an Ellipsis object?

I have a challenge where I'm given a function where I can pass only a single argument which must be a builtin (no modules of any kind), for example chr or IndexError and use its attributes and call its functions to get access to other builtin types.
For example, if I choose the getattr function, I can access the builtins like this:
def main(a):
builtins = a(a, '__self__')
main(getattr)
Most other functions aren't of much help for my challenge. I know that the attributes are deep and a lot of information can be extracted.
This is a good reference: https://book.hacktricks.xyz/misc/basic-python/bypass-python-sandboxes
What can I get access to using an Ellipsis object, in Python written as ... ?
Subclasses can be accessed using ....__class__.__base__.__subclasses__() which returns a list and eventually get access back using a for loop to find which of those classes's __name__ attribute is catch-warnings, and that class's _module attribute has all the builtins (Code). I cannot use that because the index at which it will appear is always different
The python version I target is 3.9.

AttributeError: 'builtin_function_or_method' object has no attribute 'get_valid_locations_'

I start with the assumption that I have already looked at many other posts related to the "builtin_function_or_method" error, but I have not found a solution to my problem. I really hope that someone has a moment to read because I write this post out of exhaustion.
To summarize: the following piece of code invokes the "get_valid_locations_" function
valid_locations = eval.get_valid_locations_(board)
The method I call is a function of the Evaluate class that I have previously imported in this way (I attach both how I imported the file and how I instantiated the object)
from Utilities import evaluate
eval = evaluate.Evaluate()
While the function is as follows
def get_valid_locations_(self, board):
valid_locations = []
for col in range(NUMS_COL):
if eval.is_valid_location(board, col):
valid_locations.append(col)
return valid_locations
I cannot understand what generates the error. It seems to me that the assignment and the way in which I import the class is correct, also because in the Evaluate class there are other functions that do not generate errors. So the problem I think is restricted to either the function or how it is invoked. Unless the Python compiler sees the method. I also tried to add the _ to the end of the function name but nothing.
I hope someone can help me or have some advice on how to better structure the files for projects. Thanks a lot in advance and have a nice day.
In this line that's failing:
valid_locations = eval.get_valid_locations_(board)
It sees eval as the standard Python builtin function eval. Wherever you defined it like this:
eval = evaluate.Evaluate()
The first line is not seeing that definition.
First of all, choose a different name that isn't a Python builtin to reduce confusion.
Then make sure that your use of the object eval has the correct value. If you defined it globally in a module, then from some_module import eval. Or you could pass it as an argument to a function where eval.get_valid_locations_(board) is called.
Your definition of get_valid_locations_ has a similar problem where it calls eval.is_valid_location(board, col). If get_valid_locations_ and is_valid_location are both methods of the class Evaluate, then you should call self.is_valid_location instead. Not all instances of Evaluate should necessarily be called eval, nor should they have to be defined in the same file as the class.
you created an eval object, and then trying to call get_valid_locations_ function on it.
valid_locations = eval.get_valid_locations_(board)
this is what generates the error. eval object has no get_valid_locations_ function.

TypeError: gettext() missing 1 required positional argument: 'self' - python

I'm new to python and I'm tring to make a class for a modul which checking curses in texts.
can someone help please?
import urllib
class Checktext:
def __init__(self, text):
self.text = text
def gettext(self):
file = open(self.text, "r")
filetext = open.read()
for word in filetext.split():
openurl = urllib.request.urlopen("http://www.wdylike.appspot.com/?q=" + word)
output = openurl.read()
truer = "true" in str(output)
print(truer)
s = Checktext(r"C:\Users\Tzach\.atom\Test\Training\readme.txt")
Checktext.gettext()
You declared s as a new Checktext object, so you need to call s.gettext() not an un-instantiated Checktext.gettext(), as that has no self to refer to
The urllib is a package. You have to import the module request that is located in the package:
import urllib.request
The open(filename) return a file object. You want to call the method of that object:
filetext = file.read()
And as G. Anderson wrote, you want to call s.gettext() instead of Checktext.gettext(). The self inside is actually equal to the s outside. If you want to be weird then you actually can use also:
Checktext.gettext(s)
Notice the s passed as your missing parameter. Here Python actually reveals how the Object Oriented things are implemented internally. In majority of OO languages, it is carefully hidden, but calling a method of an object is always internally translated as passing one more special argument that points to the instance of the class, that is the object. When defining a Python method, that special argument is explicitly named self (by convention; you can name it differently -- you can try as the lecture, but you should always keep that convention).
Thinking about it thoroughly, you can get the key idea of the hidden magic of an OO language syntax. The instance of the class (the object) is actually only a portion of memory that stores the data part, and that is passed to the functions that implement the methods. The Checktext.gettext is actually the function, the s is the object. The s.gettext() is actually only a different way to express exactly the same. AS s is the instance of the Checktext class, the fact is stored inside the s. Therefore, the s.gettext() creates the illusion that the rigth code will be called magically. It fits with the trained brain better than the function approach if the s is thought as a tangible something.

Using join() from both string and threading at the same time in Python

In one of my script, I used join() method from both string and threading of python. I tried to use import ... as to rename the module name like this:
import str.join as sjoin
import threading.Thread.join as tjoin
But I always cannot get the string join imported properly. I check the official doc, both join() class paths should be right. What should I do to use the two join at the same time?
EDIT
Initially I didn't import str.join(). But since I got type error, I thought I should rename the join(). But later, I realized that I passed wrong thing into the str.join(), this is the real reason why I got type error. My fault!
str.join() is a method, used on an instance of a string, so, for example:
>>> ", ".join([1, 2, 3])
1, 2, 3
No need to import anything. I use a string literal here as an example, but of course, any string can be used. This is then the 'glue' that joins the strings from the iterable (passed to the method) together.
This is also true of threading.Thread.join() - you should make an instance of the Thread class and use the join() method on that instance.
Note that due to the way Python works, you can access these methods directly from the class, then pass the instance as the first argument, however, this is generally a very bad idea, as it's harder to read and more effort than calling them normally.
str is a builtin, not a module, so you can't import from it. You could however do:
sjoin = str.join
import threading.Thread.join as tjoin

Get symbol for def in module in Python

I'm writing an interpreter for an old in-game scripting language, and so need to compile dictionary that has the name of the command from the language matched up against the symbol for that function.
Now, I've already figured out here: How to call a function based on list entry?
...That you can call functions this way, and I know that you can use dir to get a list of strings of all functions in a module. I've been able to get this list, and using a regex, removed the built-in commands and anything else I don't actually want the script to be able to call. The goal is to sandbox here. :)
Now that I have the list of items that are defined in the module, I need to get the symbol for each definition.
For a more visual representation, this is the test module I want to get the symbol for:
def notify(stack,mufenv):
print stack[-1]
It's pulled in via an init script, and I am able to get the notify function's name in a list using:
import mufprims
import re
moddefs=dir(mufprims)
primsfilter=re.compile('__.+__')
primslist=[ 'mufprims.' + x for x in dir(mufprims) if not primsfilter.match(x) ]
print primslist
This returns:
['mufprims.notify']
...which is the exact name of the function I wish to find the symbol for.
I read over http://docs.python.org/library/symtable.html here, but I'm not sure I understand it. I think this is the key to what I want, but I didn't see an example that I could understand. Any ideas how I would get the symbol for the functions I've pulled from the list?
You want to get the function from the mufprims module by using getattr and the function name. Like so:
primslist=[getattr(mufprims, x) for x in dir(mufprims) if not primsfilter.match(x) ]
I thought I might add another possible suggestion for retrieving the functions of an object:
import inspect
# example using os.path
import os.path
results = inspect.getmembers(os.path, inspect.isroutine)
print results
# truncated result
[...,
('splitdrive', <function splitdrive at 0x1002bcb18>),
('splitext', <function splitext at 0x1002bcb90>),
('walk', <function walk at 0x1002bda28>)]
Using dir on the object would essentially give you every member of that object, including non-callable attributes, etc. You could use the inspect module to get a more controlled return type.

Categories