Reputation: 233
I am wondering what is the best way to put together codes from different python files into a new python file.
Lets say the first file 1.py
would consist of:
def(...):
a=1
b=2
return c=a+b
And another file 2.py
consists of:
def(...):
d = 4
e = c*d
return e
Now let's say you have a final file, final.py
, which you want all the codes from 1.py
and 2.py
copied word by word to it in a specific order of operation where it looks as below. Note that I understand we can use the import function in python but in this case, I would like the whole text of certain definitions to be copied to the new python code. In another term, glue the codes from different files to build a new file.
final.py:
def(...):
a=1
b=2
return c=a+b
def(...):
d = 4
e = c*d
return e
EDIT:
Rephrase above: what if file 1 has 100 definitions and file 2 has 100 definitions but I want specific ones from each file copied over to file 3 with full text and syntax in a specified order.
Upvotes: 0
Views: 511
Reputation: 22773
This got a little out of hand, but I tried to re-implement it with proper structure, and this is what I came up with:
#!/usr/bin/env python3
import re
def extract_functions(code_lines, names):
# Checks if given line contains code
def is_code_line(line):
stripped = line.strip()
if stripped.startswith('#'):
return False
if len(stripped) == 0:
return False
return True
# Retreives the indentation pattern of given line
def get_indentation(line):
num_indent_chars = len(line) - len(line.lstrip())
return line[:num_indent_chars]
# Returns the function name if line has a function definition, else None
function_name_extractor = re.compile(r'^def\s+(\w+)\s*\(')
def get_function_name(line):
match = function_name_extractor.match(line)
if match is None:
return None
return match.group(1)
extracted = list()
in_function = False
for num, line in enumerate(code_lines):
# Non-code lines don't end or start functions,
# even if their indentation is wrong
if not is_code_line(line):
continue
if in_function:
# If this is the first line of the function, store the indentation
if function_indent == None:
function_indent = get_indentation(line)
# If we match the indentation, we are still in the same function.
# Store that the function includes the current line
if line.startswith(function_indent):
function_end = num + 1
# If we detect the end of the current function, extract the
# function lines and store them in 'extracted'.
else:
extracted.extend(code_lines[function_start:function_end])
in_function = False
# If we are currently not inside a function, check if current line
# contains a function start.
# Needs a separate 'if' and not just an 'else' because this code
# needs to run if the previous 'if' detected the end of a function.
if not in_function:
line_function_name = get_function_name(line)
if line_function_name is not None and line_function_name in names:
in_function = True
function_start = num
function_end = num + 1
function_indent = None
# One more extraction if the function reaches all the way to the last line
if in_function:
extracted.extend(code_lines[function_start:function_end])
return extracted
with open('1_and_2.py', 'w') as out_fil:
with open('1.py', 'r') as fil:
for line in extract_functions(fil.readlines(), ['func_a1', 'func_b1']):
out_fil.write(line)
# It isn't guaranteed that our last line in the file ends with a newline,
# Therefore add one manually
out_fil.write('\n')
with open('2.py', 'r') as fil:
for line in extract_functions(fil.readlines(), ['func_a2', 'func_b2']):
out_fil.write(line)
out_fil.write('\n')
Upvotes: 1
Reputation: 19432
You could do that in python itself!
Assuming you have a list of requiered definitions:
import re
files = ["1.py", "2.py"] # ......
defs = ["func_1", "func_2"]
with open("final.py", 'w') as out_f:
for path in files:
with open(path) as in_f:
lines = in_f.readlines()
i = 0
while i < len(lines):
line = lines[i]
r = re.search("^def\s+(\w+)\(", line)
if r:
if r.group(1) in defs:
out_f.write(line)
while i < len(lines) and not re.search("^\w", lines[i+1]): # relying on python's indent syntax
out_f.write(lines[i+1])
i += 1
i += 1
Upvotes: 2
Reputation: 77860
This is a problem in your OS tools, not Python. You're simply concatenating two text files. You can look up how to do that in your OS. If you have a favorite text editor, open a new file. Read in 1.py
; at the bottom of that, read in 2.py
; save the result as 3.py
.
Upvotes: 3