Some of the most useful features and functions in Python are Shared

  • 2020-04-02 14:36:27
  • OfStack

After many years of using Python, I stumbled upon some features and features we didn't know about before. Some are useful, but underutilized. With this in mind, I've edited some Python features you should know about.

A function with an arbitrary number of arguments
You probably already know that Python allows you to define optional parameters. But there's another way to define any number of arguments to a function.
First, take a look at an example of defining only optional parameters


def function(arg1="",arg2=""):
    print "arg1: {0}".format(arg1)
    print "arg2: {0}".format(arg2) function("Hello", "World")
# prints args1: Hello
# prints args2: World function()
# prints args1:
# prints args2:

Now, let's see how to define a function that accepts any arguments. We do this with tuples


def foo(*args): # just use "*" to collect all remaining arguments into a tuple
    numargs = len(args)
    print "Number of arguments: {0}".format(numargs)
    for i, x in enumerate(args):
        print "Argument {0} is: {1}".format(i,x) foo()
# Number of arguments: 0 foo("hello")
# Number of arguments: 1
# Argument 0 is: hello foo("hello","World","Again")
# Number of arguments: 3
# Argument 0 is: hello
# Argument 1 is: World
# Argument 2 is: Again

Use Glob() to find files
Most Python functions have long, descriptive names. But the named (link: http://docs.python.org/2/library/glob.html) as a function of what you may not know it is unless you are already familiar with it from somewhere else.
It is like a more powerful version of the function (link: http://docs.python.org/2/library/os.html#os.listdir). It lets you search for files by using pattern matching.


import glob # get all py files
files = glob.glob('*.py')
print files # Output
# ['arg.py', 'g.py', 'shut.py', 'test.py']

You can find multiple file types as follows:


import itertools as it, glob def multiple_file_types(*patterns):
    return it.chain.from_iterable(glob.glob(pattern) for pattern in patterns) for filename in multiple_file_types("*.txt", "*.py"): # add as many filetype arguements
    print filename # output
#=========#
# test.txt
# arg.py
# g.py
# shut.py
# test.py

If you want the absolute path to each file, you can call the realpath() function on the return value:


import itertools as it, glob, os def multiple_file_types(*patterns):
    return it.chain.from_iterable(glob.glob(pattern) for pattern in patterns) for filename in multiple_file_types("*.txt", "*.py"): # add as many filetype arguements
    realpath = os.path.realpath(filename)
    print realpath # output
#=========#
# C:xxxpyfunctest.txt
# C:xxxpyfuncarg.py
# C:xxxpyfuncg.py
# C:xxxpyfuncshut.py
# C:xxxpyfunctest.py

debugging

This example USES the (link: http://docs.python.org/library/inspect.html) module. This module is very useful for debugging purposes and has much more than is described here.

This article won't cover every detail of the module, but it will show you some use cases.


import logging, inspect logging.basicConfig(level=logging.INFO,
    format='%(asctime)s %(levelname)-8s %(filename)s:%(lineno)-4d: %(message)s',
    datefmt='%m-%d %H:%M',
    )
logging.debug('A debug message')
logging.info('Some information')
logging.warning('A shot across the bow') def test():
    frame,filename,line_number,function_name,lines,index=
        inspect.getouterframes(inspect.currentframe())[1]
    print(frame,filename,line_number,function_name,lines,index) test() # Should print the following (with current date/time of course)
#10-19 19:57 INFO     test.py:9   : Some information
#10-19 19:57 WARNING  test.py:10  : A shot across the bow
#(, 'C:/xxx/pyfunc/magic.py', 16, '', ['test()n'], 0)

Generate unique ID

In some cases you need to generate a unique string. I've seen a lot of people use the md5() function to do this, but it really isn't. There is actually a Python function called uuid() for this purpose.


import uuid
result = uuid.uuid1()
print result # output => various attempts
# 9e177ec0-65b6-11e3-b2d0-e4d53dfcf61b
# be57b880-65b6-11e3-a04d-e4d53dfcf61b
# c3b2b90f-65b6-11e3-8c86-e4d53dfcf61b
You may notice that even though strings are unique, the following characters look similar. This is because the generated string is associated with the computer's MAC The addresses are linked. To reduce duplication, you can use these two functions. import hmac,hashlib
key='1'
data='a'
print hmac.new(key, data, hashlib.sha256).hexdigest() m = hashlib.sha1()
m.update("The quick brown fox jumps over the lazy dog")
print m.hexdigest() # c6e693d0b35805080632bc2469e1154a8d1072a86557778c27a01329630f8917
# 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12

serialization

Have you ever needed to store a complex variable in a database or text file? You don't need to come up with a fancy way to turn an array or an object lattice into an algebraic string, because Python already provides this.


import pickle variable = ['hello', 42, [1,'two'],'apple'] # serialize content
file = open('serial.txt','w')
serialized_obj = pickle.dumps(variable)
file.write(serialized_obj)
file.close() # unserialize to produce original content
target = open('serial.txt','r')
myObj = pickle.load(target) print serialized_obj
print myObj #output
# (lp0
# S'hello'
# p1
# aI42
# a(lp2
# I1
# aS'two'
# p3
# aaS'apple'
# p4
# a.
# ['hello', 42, [1, 'two'], 'apple']

This is a native Python serialization method. In recent years, however, JSON has become popular, and Python has added support for it. Now you can use JSON to encode and decode.


import json variable = ['hello', 42, [1,'two'],'apple']
print "Original {0} - {1}".format(variable,type(variable)) # encoding
encode = json.dumps(variable)
print "Encoded {0} - {1}".format(encode,type(encode)) #deccoding
decoded = json.loads(encode)
print "Decoded {0} - {1}".format(decoded,type(decoded)) # output # Original ['hello', 42, [1, 'two'], 'apple'] - <type 'list'="">
# Encoded ["hello", 42, [1, "two"], "apple"] - <type 'str'="">
# Decoded [u'hello', 42, [1, u'two'], u'apple'] - <type 'list'="">

This is more compact and, most importantly, is compatible with JavaScript and many other languages. For complex objects, however, some of this information may be lost.

Compression characters
When we talk about compression, we usually think of files, such as ZIP structures. In Python you can compress long characters without involving any archive files.


import zlib string =  """   Lorem ipsum dolor sit amet, consectetu
                adipiscing elit. Nunc ut elit id mi ultricies
                adipiscing. Nulla facilisi. Praesent pulvinar,
                sapien vel feugiat vestibulum, nulla dui pretium orci,
                non ultricies elit lacus quis ante. Lorem ipsum dolor
                sit amet, consectetur adipiscing elit. Aliquam
                pretium ullamcorper urna quis iaculis. Etiam ac massa
                sed turpis tempor luctus. Curabitur sed nibh eu elit
                mollis congue. Praesent ipsum diam, consectetur vitae
                ornare a, aliquam a nunc. In id magna pellentesque
                tellus posuere adipiscing. Sed non mi metus, at lacinia
                augue. Sed magna nisi, ornare in mollis in, mollis
                sed nunc. Etiam at justo in leo congue mollis.
                Nullam in neque eget metus hendrerit scelerisque
                eu non enim. Ut malesuada lacus eu nulla bibendum
                id euismod urna sodales. """ print "Original Size: {0}".format(len(string)) compressed = zlib.compress(string)
print "Compressed Size: {0}".format(len(compressed)) decompressed = zlib.decompress(compressed)
print "Decompressed Size: {0}".format(len(decompressed)) # output # Original Size: 1022
# Compressed Size: 423
# Decompressed Size: 1022

Register the Shutdown function

Can module, called (link: http://docs.python.org/2/library/atexit.html), it can let you at once after the script has run some code execution.
Suppose you want to measure some baseline data at the end of the script, such as how long it has been running:


import atexit
import time
import math def microtime(get_as_float = False) :
    if get_as_float:
        return time.time()
    else:
        return '%f %d' % math.modf(time.time())
start_time = microtime(False)
atexit.register(start_time) def shutdown():
    global start_time
    print "Execution took: {0} seconds".format(start_time) atexit.register(shutdown) # Execution took: 0.297000 1387135607 seconds
# Error in atexit._run_exitfuncs:
# Traceback (most recent call last):
#   File "C:Python27libatexit.py", line 24, in _run_exitfuncs
#     func(*targs, **kargs)
# TypeError: 'str' object is not callable
# Error in sys.exitfunc:
# Traceback (most recent call last):
#   File "C:Python27libatexit.py", line 24, in _run_exitfuncs
#     func(*targs, **kargs)
# TypeError: 'str' object is not callable

The perforation seems simple enough. Just add the code to the bottom of the script, and it will run before the script ends. But if there is a fatal error in the script or the script is terminated by the user, it may not run.
When you use atexit.register(), your code will execute, and the script will stop running for whatever reason.

conclusion

Do you realize that Python features that are not well known are useful? Share them with us in the comments. Thanks for reading!


Related articles: