Python organizing project with extensions like Swift - python

I am new to python coming from Swift. In Swift I can create a new file and add code to an existing class using the extension key word. Does python have a similar way to do this or does all source code need to be in a single file?
I would like to do this to help organize my project.

In Python, functions are first-class citizens. This means that you can assign functions to names just like you assign other values. In particular, you can add a function to a class like this:
class Foo:
def foo(self):
print('foo')
def bar(self):
print('bar')
Foo.bar = bar
f = Foo()
f.foo()
f.bar()
Note that even though bar() is declared globally, it still must take at least one parameter. Traditionally, the first parameter of member functions is called self but this is only a convention and is not enforced by the language.

Python will also look in the same director as your base file when using the import or from keywords.
to build on Code-Apprentice's answer, you can also inherit easily from a class like this (if you wanted to extend the functionality of the list class:
class NewList(list): # inherit from the list class
#property
def sqrt_len(self):
return len(self) ** .5
nl = NewList([1, 2, 3, 4])
print(nl.sqrt_len) # prints "2.0" to stdout
You could then put newlist.py in the same directory as another .py and use import newlist or from newlist import NewList
A word of caution, make sure there isn't a name collision with your file and the name of another package that you want to use as python will import the files in the same directory first.

Related

create a function with dot: myfunc.print("Hello World") in python

how do you define dotted function?
i try this:
def myfunc.print(value)
print(value);
but it's said "Invalid syntax"
In python, and in many other languages, the "dot" syntax is a product of code organizational structure. So, X.Y tells python to look for Y inside of X. There are actually a few ways to do this. You can define a class which organizes a set of functions and properties within the class or its associated objects (as #Samwise's answer shows). You can also create a new file "myfunc.py", and have one of the functions defined in that file be def print(): pass - then when you import myfunc in another file you can access myfunc.print. In any case, the dot represents a "belonging" relationship, so you need to have your print function "belong" to the myfunc containing structure in some way.
Here's one way:
>>> class myfunc:
... print = print
...
>>> myfunc.print("foo")
foo
In this example, myfunc is actually a class, and print is a class attribute (which is initialized to point to the print function).

Getting functions from Python file as passable objects

I have a Python file from which I would like to get all functions. I want to pass these functions to another file in order to collect data about these functions.
For Example.py:
class Example:
def method_to_extract(name: str) -> none:
print(name)
I want to extract this method as an object through the file name and pass it as an argument to another function, like
func = magic_method(Example.py) # returns method_to_extract as a callable object
collect_data(func)
Is this possible? So far, I have only been able to extract the names of functions as strings. However, that does not help me, as I want to collect data about the functions like the number of arguments, type hints, and more, and therefore need to be able to access the entire function.
I also tried getting the function using func = getattr(class, funcname), but I wasn't able to pass func as a parameter and extract the data I need.
I can think of 3 solutions, dependant on your particular needs.
Simplest one: don't use classes, just global functions:
# file1.py
def method_to_extract(name):
print(name)
And then in another file just import and use it:
# file2.py
from file2 import method_to_extract
method_to_extract()
In case you especially want to use methods inside of a class, you can make them static with #staticmethod decorator:
# file1.py
class Example:
#staticmethod
def method_to_extract(name):
print(name)
And then in another file just import and use it:
# file2.py
from file2 import Example
Example.method_to_extract()
More on staticmetod decorator here: https://www.programiz.com/python-programming/methods/built-in/staticmethod
Of course, not all of your methods can be static. Then you just have to create an instance of the class and then use its methods:
# file1.py
class Example:
def method_to_extract(name):
print(name)
And then in another file just import and use it:
# file2.py
from file2 import Example
instance = Example()
instance.method_to_extract()
Basically, the above three approaches are in general only possible ways of accessing some particular function or method in python and the fact of exporting them to another file doesn't change a thing.
Something like this:
from Example import Example.method_to_extract as mte
collect_data(mte)
The code you show is not entirely correct; you would have to make method_to_extract a #staticmethod if it's inside the Example class. Perhaps a better solution then would be to define it outside the class; or define a #classmethod which you can call to return a method of that class as an object. But both of these are generally best avoided; your class should probably simply have a method which implements collect_data, and your code should simply call that instead.

How to make a python class not exposed to the outside?

I'm relatively new to Python.
When I did C/C++ programming, I used the internal classes quite often. For example, in some_file.cc, we may implement a class in the anonymous namespace to prevent it from being used outside. This is useful as a helper class specific to that file.
Then, how we can do a similar thing in Python?
class MyClassOuter:
def __init__(self,...):
class MyClassInner:
def __init__(self,...):
pass
self.my_class = MyClassInner(..)
would only have MyClassInner available inside the __init__ function of MyClassOuter
likewise you could put it inside a function
def my_class_factory(arg1,arg2,...):
class MyClass:
def __init__(self,arg1,arg2,...):
print "OK??"
return MyClass(arg1,arg2,...)
Python code doesn't have any such equivalent for an anonymous namespace, or static linkage for functions. There are a few ways you can get what you're looking for
Prefix with _. Names beginning with an underscore are understood
to be for internal use to that python file and are not exported by
from * imports. it's as simple as class _MyClass.
Use __all__: If a python file contains a list a list of strings
named __all__, the functions and classes named within are
understood to be local to that python file and are not exported by
from *.
Use local classes/functions. This would be done the same way you've
done so with C++ classes.
None these gets exactly what you want, but privacy and restricting in this way are just not part of the language (much like how there's no private data member equivalent). Pydoc is also well aware of these conventions and will provide informative documentation for the intended-to-be-public functions and classes.

python, how to detect attributes or functions that defined in class but never called by the instance of class?

As you know, when the project's code is very large and there are so many attributes and functions defined in a Class, but some of them never be called by the instance of the Class, and maybe some of them has been discarded. Here is a example:
class Foo(object):
""""""
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
...
self.y = 25
self.z = 26
def func1(self):
pass
def func2(self):
pass
def func3(self):
pass
...
...
def func100(self):
pass
if __name__ == '__main__':
f = Foo()
f.func1()
f.func2()
print f.a, f.b, f.z
In the above code, the instance f of class Foo just called func1() and func2(). And how to find all the attributes and functions of class that never called by the instance of class.
I have tried compiler module but that could not solve my question. And dir(my_instance) is just print all the functions and attributes defined the the class.
Thanks in advance.
You can try coverage.py. It's not static analysis, but actually runs your code and records which statements are executed, outputting annotated html or txt as you wish (quite nicely formatted as well). You can then look for functions and methods whose bodies are not executed at all.
This still doesn't take care of unused attributes. And I don't know the answer to that. Maybe comment them out one at a time and see if tests still pass...
It's pretty hard to prove something is or is not used in the general case. Python is a dynamic language; if even one bit of code calls into code the static analyzer doesn't fully analyze, it could be accessing the variables mentioned.
The pylint and flake8 tools will tell you about local and global names that aren't defined prior to use (unless you break them by using from x import * style imports), and about imports that are never used (an import that is never used is usually wrong, but even then, it could be an intentional part of the interface, where linters would have to be silenced), but I don't believe they can tell you that a given attribute is never accessed; after all, someone else could import your module and access said attributes.
Use the profile module in the standard library.
python -m cProfile -o output_file myscript.py
Then load the stats file and use print_callees() to get all the functions that were called--during that run of the program.
I don't know of any easy way to find out which attributes are used.

Python module object without a file

I was just curious if it was possible to create a module object inside python at runtime, without loading from any python file. The purpose of this would be to create a new empty namespace where other objects can then be stored subsequently. If this is not possible, is there another way to make and pass namespaces in python without saving to disk?
You can use a class with static methods.
class Namespace:
#staticmethod
def greet():
print "hello, world!"
In Python 3 the #staticmethod decorator is not needed.
You can use a simple class:
class Namespace:
pass
Now, to create a new namespace:
n = Namespace()
To store things in the namespace:
n.foo = 1
def square(x):
return x*x
n.squared = square
To refer to things in the namespace:
print n.foo
print n.squared(12)
To pass the namespace:
def func_requiring_a_namesapce(space):
print space.foo
func_requiring_a_namespace(n)
You could use a dictionary?
Modules Are Like Dictionaries
You know how a dictionary is created and used and that it is a way to map one thing to another. That means if you have a dictionary with a key 'apple' and you want to get it then you do this:
mystuff = {'apple': "I AM APPLES!"}
print mystuff['apple']
Imagine if I have a module that I decide to name mystuff.py and I put a function in it called apple. Here's the module mystuff.py:
# this goes in mystuff.py
def apple():
print "I AM APPLES!"
Once I have that, I can use that module with import and then access the apple function:
import mystuff
mystuff.apple()
I could also put a variable in it named tangerine like this:
def apple():
print "I AM APPLES!"
# this is just a variable
tangerine = "Living reflection of a dream"
Then again I can access that the same way:
import mystuff
mystuff.apple()
print mystuff.tangerine
Refer back to the dictionary, and you should start to see how this is similar to using a dictionary, but the syntax is different. Let's compare:
mystuff['apple'] # get apple from dict
mystuff.apple() # get apple from the module
mystuff.tangerine # same thing, it's just a variable
In the case of the dictionary, the key is a string and the syntax is [key]. In the case of the module, the key is an identifier, and the syntax is .key. Other than that they are nearly the same thing.
Editied from here

Categories