I have a class and I need to use string input to create it and I've heard about exec(), so I tried using that and I put the string in properly yet it gives me errors, this is the exec line:
exec(" ".join(args[2:])).toString()
The first 2 parts of the list are not relevant. I debugged this string just to see it is correct and even tried to hardcode it and it worked, but it didn't when I used exec.
What is wrong with this and how can I make this right?
Appreciating all the comment :)
Edit:
The error I get is AttributeError saying it is a NoneType, although if I just hardcode it it works perfectly fine.
Solution 1: instead of passing a Python expression, either use argparse's subcommands or define your own easily-parsable mini-language. You can store relevant classes and functions in a dict to get them from strings (better than relying on globals as it lets you whitelist only what you want to expose)
Solution 2: use the full power of the ast module to parse the Python expression into an ast then write your own visitors to safely evaluate the ast.
Solution 3: keep on using exec or eval and wait until some script kiddie erases your full hard-drive or worse.
This question already has an answer here:
python string module vs str methods
(1 answer)
Closed 6 years ago.
I am new to programming therefore may sound idiotic. I am learning python where I am not able to understand how few methods like upper(), split() etc work.
I mean you directly use like below:
"ABC".upper() or "abc,xyz".split(",")
Or, you can first import string and then call these methods like below:
import string
string.upper("abc")
string.split("abc,xyz", ",")
What is the difference, and how would we import string module when we can achieve the same output without importing it.
Are there similar cases exist apart from string module?
In fact, one of the paradigm you can use in Python is the Object Oriented Programming, where you modify object state through "methods" like this: myobject.mymethod().
Syntactically, it means that the first argument of the method mymethod() is in fact the object itself. But, as Python want also to deal with other paradigms (functional programming, imperative programming, and so on), there is two syntactical ways to address this method.
One is simply as I mentioned before: myobject.mymethod(), and the other one is simply to consider that the first argument is the object itself: mymethod(myobject).
More precisely, you can realize that when you define by yourself a method because you have to specify the first argument by self which is a reference to the object itself like this:
def mymethod(self):
pass
Is it possible to wrap the method name in the definition of a function? I have an exceptionally long method name and I'm wondering if it's possible to wrap it like so:
# method name is my_really_long_method_name_wow_this_is_really_long
def my_really_long_method_name_
wow_this_is_really_long():
pass
I have tried doing this, but I get a syntax error:
def my_really_long_method_name_\
wow_this_is_really_long():
pass
No, wrapping your function name is not possible, even if Python supports unlimited length of function names. Longer function names are not unusual, but making them so long they need two rows of a screen actually shows something is really wrong with your naming convention.
Btw, Python recommends a line length (in total) of 79 characters. We are not in the 80's anymore with old screens so you can ignore that limit, but it gives you a good indication.
Reference: PEP 0008 -- Style Guide for Python Code
I'm asking about situations where if a wrong type of argument is passed to the function, it could:
Blow up the whole thing.
Return unexpected results
Return nothing
For instance, the function below expects the argument name to be a string. It would throw an exception for all other types that doesn't have a startswith method.
def fruits(name):
if name.startswith('O'):
print('Is it Orange?')
There are other cases where a function could halt or cause damage to the system if execution proceeds without type-checking. Whenever there are a lot of functions or functions with a lot of arguments, type checking is tedious and makes the code unreadable. So, is there a standard for doing this? As to 'how to type check' - there are plenty of examples here on stackexchange, but I couldn't find any about where it would be appropriate to do so.
Another example would be:
def fruits(names):
with open('important_file.txt', 'r+') as fil:
for name in names:
if name in fil:
# Edit the file
Here if the name is a string each character in it will influence the editing of the file. If it is any other iterable, each element provided by it would influence the editing. Both of these could produce different results.
So, when should we type-check an argument and should we not?
The answer off the top of my head would be: it depends where the input comes from.
If the functions are class methods that get invokes internally or things like that, you can assume the inputs are valid, because you wrote it!
For example
def add(x,y):
return x + y
def multiply(a,b):
product = 0
for i in range(a):
product = add(product, b)
return product
In my add function, I could check that there is a + operator for the parameters x and y. But since I wrote the multiply function, and that is the only function that uses add, it is safe to assume the inputs will be int because that's how I wrote it. Now that argument stands on shaky ground for large code bases where you (hopefully) have shared code, so you can't be sure people don't misuse your functions. But that's why you comment them well to describe the correct use of said function.
If it has to read from a file, get user input, etc, then you may want to do some validation first.
I almost never do type checking in Python. In accordance with Pythonic philosophy I assume that me and other programmers are adult people capable of reading the code (or at least the documentation) and using it properly. I assume that we test our code before we let it destroy something important. After all in most cases if you do something wrong, you'll just see an error and Python's error messages are quite informative most of the time.
The only occasion when I sometimes check types is when I want my function to behave differently depending on the argument's type. But although I sometimes feel compelled to do this, I don't consider it a good practice.
Most often it happens when my function iterates over a list of strings and I fear (or want) I could get a single string passed into it by accident - this won't throw an error at once because unfortunately string is an iterable too.
Is there a generally accepted way to comment functions in Python? Is the following acceptable?
#########################################################
# Create a new user
#########################################################
def add(self):
The correct way to do it is to provide a docstring. That way, help(add) will also spit out your comment.
def add(self):
"""Create a new user.
Line 2 of comment...
And so on...
"""
That's three double quotes to open the comment and another three double quotes to end it. You can also use any valid Python string. It doesn't need to be multiline and double quotes can be replaced by single quotes.
See: PEP 257
Use docstrings.
This is the built-in suggested convention in PyCharm for describing function using docstring comments:
def test_function(p1, p2, p3):
"""
test_function does blah blah blah.
:param p1: describe about parameter p1
:param p2: describe about parameter p2
:param p3: describe about parameter p3
:return: describe what it returns
"""
pass
Use a docstring, as others have already written.
You can even go one step further and add a doctest to your docstring, making automated testing of your functions a snap.
Use a docstring:
A string literal that occurs as the first statement in a module, function, class, or method definition. Such a docstring becomes the __doc__ special attribute of that object.
All modules should normally have docstrings, and all functions and classes exported by a module should also have docstrings. Public methods (including the __init__ constructor) should also have docstrings. A package may be documented in the module docstring of the __init__.py file in the package directory.
String literals occurring elsewhere in Python code may also act as documentation. They are not recognized by the Python bytecode compiler and are not accessible as runtime object attributes (i.e. not assigned to __doc__ ), but two types of extra docstrings may be extracted by software tools:
String literals occurring immediately after a simple assignment at the top level of a module, class, or __init__ method are called "attribute docstrings".
String literals occurring immediately after another docstring are called "additional docstrings".
Please see PEP 258 , "Docutils Design Specification" [2] , for a detailed description of attribute and additional docstrings...
The principles of good commenting are fairly subjective, but here are some guidelines:
Function comments should describe the intent of a function, not the implementation
Outline any assumptions that your function makes with regards to system state. If it uses any global variables (tsk, tsk), list those.
Watch out for excessive ASCII art. Having long strings of hashes may seem to make the comments easier to read, but they can be annoying to deal with when comments change
Take advantage of language features that provide 'auto documentation', i.e., docstrings in Python, POD in Perl, and Javadoc in Java
I would go for a documentation practice that integrates with a documentation tool such as Sphinx.
The first step is to use a docstring:
def add(self):
""" Method which adds stuff
"""
Read about using docstrings in your Python code.
As per the Python docstring conventions:
The docstring for a function or method should summarize its behavior and document its arguments, return value(s), side effects, exceptions raised, and restrictions on when it can be called (all if applicable). Optional arguments should be indicated. It should be documented whether keyword arguments are part of the interface.
There will be no golden rule, but rather provide comments that mean something to the other developers on your team (if you have one) or even to yourself when you come back to it six months down the road.
I would go a step further than just saying "use a docstring". Pick a documentation generation tool, such as pydoc or epydoc (I use epydoc in pyparsing), and use the markup syntax recognized by that tool. Run that tool often while you are doing your development, to identify holes in your documentation. In fact, you might even benefit from writing the docstrings for the members of a class before implementing the class.
While I agree that this should not be a comment, but a docstring as most (all?) answers suggest, I want to add numpydoc (a docstring style guide).
If you do it like this, you can (1) automatically generate documentation and (2) people recognize this and have an easier time to read your code.
You can use three quotes to do it.
You can use single quotes:
def myfunction(para1,para2):
'''
The stuff inside the function
'''
Or double quotes:
def myfunction(para1,para2):
"""
The stuff inside the function
"""
The correct way is as follows:
def search_phone_state(phone_number_start,state,dataframe_path,separator):
"""
returns records whose phone numbers begin with a phone_number_start and are from state
"""
dataframe = pd.read_csv(filepath_or_buffer=dataframe_path, sep=separator, header=0)
return dataframe[(pd.Series(dataframe["Phone"].values.tolist()).str.startswith(phone_number_start, na="False"))& (dataframe["State"]==state)]
If you do:
help(search_phone_state)
It will print:
Help on function search_phone_state in module __main__:
search_phone_state(phone_number_start, state, dataframe_path, separator)
returns records whose phone numbers begin with a phone_number_start and are from state