Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Sometimes when writing python software I end up in a situation in which I am not sure whether to use a function with sub functions, or just a class. In these cases, I have a series of distinct inputs, I want to apply some transform to them and then produce a distinct output. And I don't much care about any of the variables that are created in the process of going from inputs to outputs. So it feels like it should be a simple function in this sense rather than a Class. But for these cases, its also quite a complex series of operations that are involved, often with a need for sub functions that are only useful in the process of transforming the inputs to outputs and not in any more general sense.
And at the end of the day, I usually just want to call it using:
output = my_function(input)
So I can do something like
def my_function(input):
def subfunc1(blah):
return blah1output
def subfunc2(blah):
return blah2output
#lots of complex code here that calls subfunc1 and subfunc2
return output
But then co-worker X might come along and say, wow that looks like a pretty complex function, you should use a class! OR I could do this
class my_function(object):
def __new__(self, input):
#lots of complex code here that calls subfunc1 and subfunc2
return output
#staticmethod
def subfunc1(blah):
return blah1output
#staticmethod
def subfunc2(blah):
return blah2output
But, this seems to be like an odd use for a class because I don't really care about creating and maintaining instances of the class.
A major advantage of using classes here though is that you can more easily test subfunc1 and subfunc2 and this alone might be sufficient reason to use one.
However, as I'm still new to programming can someone suggest the best possible solution for a production environment and/or the solution that is generally most pythonic?
#wwii's comment is the right answer.
To elaborate, you are correct in your intuition that it might not be pythonic to create a class that will function as a singleton - modules are the preferred way to do this (here's an oblique reference in the programming faq).
You are also correct that it is good to be able to test your subfunctions. One other reason to pull them out of the function body is because Python, as an interpreted language, will otherwise rebuild the subfunction inside every time that your outer function is called.
Benjamin Gleitzman's glorious howdoi module (the link is to his github repo) is a beautiful example of how to break out a complex problem into small, very readable pieces -- following the PEP 8 philosophies that "flat is better than nested" and "simple is better than complex"
edit
Here's an example of a simple module (python tutorial on modules) that can mask your internal functions. The structure is:
mymodule
|____
|___ __init__.py
|___ submodule.py
in __init__.py:
"""
This docstring shows up when someone does `help(mymodule)`.
"""
from submodule import my_function
in submodule.py:
def _subfunc1(x):
"""A preceding underscore signals to the reader that it's an internal function."""
return x + 1
def _subfunc2(x):
return x * 2
def my_function(x):
"""Yours will be cooler."""
return _subfunc1(x) * _subfunc2(x)
And to use it:
>>> import mymodule
>>> result = mymodule.my_function(5)
>>>
>>> # But internal functions (not imported) won't be visible...
>>> mymodule._subfunc1(5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute '_subfunc1'
Related
This question already has answers here:
Can you add new statements to Python's syntax?
(13 answers)
Closed 2 months ago.
Not sure how to explain, I mean statemtents like:
for i in l:
if a==b:
def x():
lambda x:
class spam:
while True:
basically those control statements that end with :
can I create novel ones? (like in snakemake that has a long list of new control statements)
I tried reading documentation, but could not find anything useful.
I just want to make some tools to help develop rules for snakemake.
I am currently using this:
class SM(object):
def __init__(self,**xargs):
self.items = xargs
def __getattribute__(self,attr):
return object.__getattribute__(self, "items")[attr]
input = SM(genome="Genome/genome.fa",
table="rmats/binding_strength.maxent.CLIP.csv")
table = pd.read_csv(input.table,index_col=0)
In that example I can use the class SM to emulate all the input, output, wildcard... then I can just move the code into its rule in the Snakefile without needing to manually edit all the inputs/wildcards/outputs...
However, I will still need to write the "input:".
Is there a way I could make:
input:
table="table.csv"
do
input=SM(table:"table.csv")
#or input=SM(**xargs)
Sorry, but no can do...You would have to modify the language implementation itself (the interpreter actually). When you are programming you are bound by the syntax of the language, you cannot modify the syntax "on the fly". It's not the same as e.g. defining functions, classes and whatnot.
Take a look at these:
Can you add new statements to Python's syntax?
How to make custom reserved keywords in python3
Here's the most comprehensive answer to this kind of questions imho:
https://stackoverflow.com/a/9108164/15923186
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
What does "call" mean and do? How would you "call" a function in Python?
When you "call" a function you are basically just telling the program to execute that function. So if you had a function that added two numbers such as:
def add(a,b):
return a + b
you would call the function like this:
add(3,5)
which would return 8. You can put any two numbers in the parentheses in this case. You can also call a function like this:
answer = add(4,7)
Which would set the variable answer equal to 11 in this case.
I'll give a slightly advanced answer. In Python, functions are first-class objects. This means they can be "dynamically created, destroyed, passed to a function, returned as a value, and have all the rights as other variables in the programming language have."
Calling a function/class instance in Python means invoking the __call__ method of that object. For old-style classes, class instances are also callable but only if the object which creates them has a __call__ method. The same applies for new-style classes, except there is no notion of "instance" with new-style classes. Rather they are "types" and "objects".
As quoted from the Python 2 Data Model page, for function objects, class instances(old style classes), and class objects(new-style classes), "x(arg1, arg2, ...) is a shorthand for x.__call__(arg1, arg2, ...)".
Thus whenever you define a function with the shorthand def funcname(parameters): you are really just creating an object with a method __call__ and the shorthand for __call__ is to just name the instance and follow it with parentheses containing the arguments to the call. Because functions are first class objects in Python, they can be created on the fly with dynamic parameters (and thus accept dynamic arguments). This comes into handy with decorator functions/classes which you will read about later.
For now I suggest reading the Official Python Tutorial.
To "call" means to make a reference in your code to a function that is written elsewhere. This function "call" can be made to the standard Python library (stuff that comes installed with Python), third-party libraries (stuff other people wrote that you want to use), or your own code (stuff you wrote). For example:
#!/usr/env python
import os
def foo():
return "hello world"
print os.getlogin()
print foo()
I created a function called "foo" and called it later on with that print statement. I imported the standard "os" Python library then I called the "getlogin" function within that library.
when you invoke a function , it is termed 'calling' a function .
For eg , suppose you've defined a function that finds the average of two numbers like this-
def avgg(a,b) :
return (a+b)/2;
now, to call the function , you do like this .
x=avgg(4,6)
print x
value of x will be 5 .
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
def function(x+4):
return (x*5)+3
SyntaxError: invalid syntax
Why is that? i don't get the logic behind it?
(i know that it is a simple question but i couldn't find an answer to it.
i got many unclear feedbacks about my question,i am sorry about that as english is not my first language i couldn't clarify my question in short:
While i was learning about what return does,i compromised the logic with the logic behind f(x)= codomain as def function(x) = return codomain
but as you know there are functions in maths like f(x+2) = 5x+3. I thought maybe i could do the same on def function,the problem was it was giving a syntax error ,and i was curious about the design idea behind it and if there was an alternative solution to implement this in code.Thanks for answers!
This is a rather uncommon syntax you are suggesting and it is simply not part of Python's syntax, or any language that I know.
Although, what you want to do boils down to updating an argument before it is passed to a function. This can be done with a decorator.
def add_four_to_argument(f):
return lambda x: f(x + 4)
#add_four_to_argument
def func(x):
return (x*5)+3
print(func(1)) # 28
Since you asked about the logic behind that design decision, how would you expect that syntax to behave? Note that it is not the same x being shared everywhere. The following are the same:
x = 5
def f(x):
return x
print(f(x)) # Prints 5
x = 5
def f(y):
return y
print(f(x)) # Prints 5
This allows you to scope your variables and not have to debug the confusing shared state that exclusive use of global variables can cause.
Back to your question though, nowhere else in Python does the addition operator cause assignment (barring abuse of dunder methods...don't do that). So, in your hypothetical f(x+4), what happens to the x+4? Is that supposed to be a placeholder for x=x+4, or is that supposed to be assigned to some new variable representing some ethereal notion of "argument 1" for the function?
Let's dive into it a little further. What about the following example:
def f(x+y):
return x
Suddenly things got a whole lot more ambiguous. How do we call this function? Do we use f(1,2)? Do we only pass a single argument f(3) and guess which portion corresponds to x and which corresponds to y? Even if we figure out the semantics for calling such a function, what does the statement x+y actually do? Does it stand for x=x+y? For y=x+y? For arg1=x+y?
By not allowing the behavior you're describing, Python makes your intent clear. To do a thing, you have to tell Python to actually do that thing. From the Zen of Python,
explicit is better than implicit.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
In python, I can do something like this:
# say.py
class Speaker:
def speak(self,word):
pass
def Do(self):
self.speak("hello")
Speaker().Do()
If I run this, it would do nothing at all. I can do this in another module:
import say
class Test(say.Speaker):
def speak(self,word):
print(word)
Test().Do()
If I run this, the original speak function in say.py is overwritten completely since I inherited it when I did:
class Test(say.Speaker)
So when I run the script, it will print the word rather than doing nothing. I want the name of the script to dynamically change file names without having to edit say.rb.
If I ran say.py and did:
Speaker().do()
nothing happens, but when I run the other py module, and have it do:
Test.Do()
it is overwritten since I inherited it, and changed the function of speak. Doing Speaker().Do() as it is does nothing, but if I do Test.Do(), it does work because of the override.
Is their a ruby equivalent for what I did in python, and if so, how would I do it?
It is very similar. Here's 'say.rb':
module Say
class Speaker
def speak(word) end
def Do() speak("Hello") end
end
end
In your other module:
require 'say'
class Test < Say::Speaker
def speak(word)
puts(word)
end
end
To demonstrate:
Test.new.Do
Of course there is. What have you tried that didn't work? Read up on inheritance in Ruby.
You'd literally need only change a few characters in that Python to get it to work in Ruby.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I often see some code with
def main(A,B)
some steps
described as an "overloading for the main function", after reading something more specific about Python I know that this is not true because:
Python is a loseless type language
a function/method in Python doesn't even know the type for a given parameter, nor python cares
I'm also not sure if there is a real distinction between instances and "static methods" or "class methods", probably they are the same thing and the only difference is given by the use of decoratos, but this is probably related to my first approach to a functional language after spending so much time with C/C++ .
Even more, in Python, the first indentation level is used as an entry point ( like main() in C/C++ ), so I don't get why you should define a main at an indentation level that is different from the really first one.
The general idea that I have about Python's keywords is that the keywords have a special semantic value rather than a real defined syntax ( probably it's because the C++ is less "idiomatic" , I don't really know how explain that ), they are used as a placeholder for something and they give a special meaning to the section where they are applied. There also special variables like __name__ that are there just to store special informations and nothing more.
After all this small bits of information stored in my brain I still dont' get the real meaning of the first code example:
what is special about the main() function ?
what is the point of defining something like a "main" function if it's not real "main"
how Python decide what function is the one to call if it's not typed ?
there is a difference between how the interpreter reads __init__.py files and other files ?
To answer your questions:
main() function
Nothing is special about it. You have to call it yourself, by doing something like:
def main():
print "This is main"
if __name__ == "__main__":
main()
Why use main()
The reason you might do that is to keep your main entry-point code together in a convenient way. For instance, if you create some variables in main(), they won't be global variables, which avoids polluting the global namespace. It also prevents the main() function from being run if you import the module from another (instead of running it directly as a script). This can be useful if you don't want to do some initialization (e.g., print messages) when importing, but you do want to do them when running as a standalone script.
How does Python decide which function to call
Python does not support "overloading" in this sense. There can only be one function with a given name in a given namespace. If you make a second function with the same name (or second method with the same name in the same class), you overwrite the first one completely.
__init__.py
This question is not really related to your others. But no, it doesn't process them in a different way. It processes them at a different time (when you import a package, rather than a module in a package), but the code in them is run just the same as the code in any other Python file.
main() in python is just a function name. The common idiom
if __name__ == '__main__':
#do something
is a shortcut to figure out of the code in this file is being run as a program rather than imported as a module.
Because python is intended to by type-free, the community puts a strong emphasis on conventions and best practices. This doesn't provide the same level of predictability as a compiler, but it helps keep the chaos at bay. Readability is a core python value and idioms like this provide valuable structure.
Python does not support function overloading in the sense that other languages do. In strongly typed languages you might write multiple versions of the same function with the same name but varying input arguments:
void DoSomething (int a) {};
void DoSomething (float f) {};
void DoSomething (string s){};
In python there is no equivalent idiom. In most cases it's unneeded: for a numeric operation you don't really care if the incoming numbers are floats, ints or whatever -- only that they support the correct operators. This is where the python mantra of 'duck typing' comes in - if it walks like a duck and quacks like a duck, it's a duck. So python functions idiomatically look for functions or operators on incoming arguments rather than checking their types.
As for instance vs static methods:
In python every instance method implicitly gets the owning instance as the first argument to a function:
class Test(object):
def __init__(self, arg):
self.variable = arg
def example(self):
print self.variable
fred = Test(999) # note: no 'self' passed here
fred.example()
>>> 999
joe = Test(-1)
joe.example()
>>> -1
a class method gets the class type, rather than an instance, as the implicit first argument. Class methods can see class-level variables, which are defined in the class scope rather than in the instance scope - but they don't know anything about a particular instance.
class TestCls (Test)
CLASS_VARIABLE = "hello"
# other behavior inherited from Test
#classmethod
def class_example(cls):
print cls.CLASS_VARIABLE
barney = TestCls(123)
barney.example()
>>> 123
barney.class_example() # again, no explicit class passed in
>>> 'hello'
a static method gets no implicit arguments at all:
class TestStatic (TestCls):
CLASS_VARIABLE = 'goodbye'
# inherited stuff again
#staticmethod
def static_test():
print "behold, I have no implicit argument"
Static and class methods also don't need an instance to be called:
wilma = TestStatic(123)
wilma.static_test() # you can call from an instance
>>> behold, I have no implicit argument
# or not:
TestStatic.static_test()
>>> behold, I have no implicit argument
TestStatic.class_example()
>>> goodbye # the method is inherited, but the class variable come from this class