1

2024-11-08 09:07:01

Python Programming Basics: From Beginner to Expert!

Language Features

yield and Generators

Have you ever experienced this: when programming, you need to process large amounts of data, but memory space is limited, making it difficult and slow to process? Then come learn about generators in Python!

Generators are a special type of iterator in Python. By using the yield keyword, functions can become generators, producing values one by one as needed, instead of generating all values into memory at once. This technique is called "lazy evaluation".

Let's look at an example. If you want to generate a list of numbers from 1 to 1000000, the traditional approach is:

nums = [x for x in range(1000001)]

This consumes a lot of memory. Using a generator is much more efficient:

def count(n):
    i = 0
    while i < n:
        yield i 
        i += 1

nums = count(1000001)

Now nums is a generator object, and each call to next(nums) generates a new value, without consuming too much memory. Cool, isn't it?

The biggest advantage of generators is saving memory. You can think of it as a water pipe, only flowing out new values when needed, without wasting space. In big data scenarios, this technique can play an important role. So hurry up and learn about yield and generators to make your code more efficient!

What are Metaclasses?

Have you heard the phrase "classes are objects"? In Python, classes are also objects, created by metaclasses. Metaclasses can be called "classes of classes".

Metaclasses are mainly used to control the behavior of classes, such as deciding which methods a class should include. If you're not satisfied with the class creation process, you can customize this process by writing metaclasses.

This might sound a bit confusing, but don't worry too much about it. For most Python developers, using Python's built-in type class as a metaclass is sufficient. Unless you really need to intervene in class creation, you don't need to delve into the details of metaclasses for now.

However, I still want to share an interesting example. Suppose we want all class attribute names to start with an underscore to avoid potential naming conflicts, we can write a metaclass like this:

class PrefixMetaclass(type):
    def __new__(cls, name, bases, attrs):
        new_attrs = {}
        for attr_name, attr_val in attrs.items():
            new_attrs["_" + attr_name] = attr_val
        return super().__new__(cls, name, bases, new_attrs)

class MyClass(metaclass=PrefixMetaclass):
    x = 1
    y = 2

obj = MyClass()
print(obj._x) # Outputs 1

By customizing metaclasses, we can modify a class's attributes during its creation. This "black magic" is very useful in framework design, but as a beginner, you only need to understand the existence and function of metaclasses for now.

File Operations

Checking if a File Exists

In programming, it's often necessary to check if a certain file exists. In Python, there are many ways to do this. Let's analyze them one by one:

  1. os.path.exists(path)

This is the most commonly used method. It can check not only files but also if directories exist:

import os

file_path = "/path/to/file.txt"
dir_path = "/path/to/dir"

print(os.path.exists(file_path)) # True if the file exists
print(os.path.exists(dir_path)) # True if the directory exists
  1. os.path.isfile(path)

This function is specifically used to check if a given path is an existing file:

print(os.path.isfile(file_path)) # True if it's an existing file
print(os.path.isfile(dir_path)) # False, because this is a directory
  1. pathlib.Path

Starting from Python 3.4, the standard library added the pathlib module, which provides an object-oriented way to handle paths:

from pathlib import Path

my_file = Path("/path/to/file.txt")
print(my_file.exists()) # True if the file exists
  1. os.access

This method can be used to check if a file exists and its permissions:

print(os.access(file_path, os.F_OK)) # True if the file exists

All these methods can correctly determine if a file exists. However, I personally prefer using os.path.exists() because it's simple, straightforward, and has good readability. Of course, if you need to check more file attributes, other methods are also useful.

File Operation Functions

Besides checking if a file exists, Python also provides many other file operation functions, such as opening, reading/writing, copying, etc. Let's quickly go through the commonly used ones:

  • open()
    • Opens a file and returns a file object
    • Using a with statement can automatically close the file
  • file.read()/write()
    • Read/write file contents
  • file.close()
    • Close an opened file
  • os.remove()
    • Delete a file
  • os.rename()
    • Rename a file
  • shutil.copy()/copytree()
    • Copy a file/directory
  • os.mkdir()/makedirs()
    • Create a directory

The usage of these functions is very intuitive, and you can refer to the Python documentation to learn about specific parameters and usage.

However, one thing to note is that when operating on files, make sure you have sufficient permissions. Otherwise, it may raise exceptions like PermissionError.

My personal advice is: try to use context managers (with statements) to automatically close files whenever possible, which can avoid resource leaks due to improper manual closing. Also, be extra careful when copying or deleting files, and make adequate backups.

Conditions and Expressions

Ternary Operators

Python has a very concise conditional expression called the "ternary operator". It can complete the function of if...else... in one line of code, written as follows:

value_if_true if condition else value_if_false

For example, if we want to return the absolute value of a number x or itself based on whether it's positive or negative:

x = -5
result = x if x >= 0 else -x
print(result) # Outputs 5

Don't you think this is more concise than the traditional if...else... writing?

The biggest advantage of ternary operators is good readability and concise code. It's suitable for simple conditional judgment scenarios.

However, if the condition is too complex, I still recommend using the complete if...else... statement, which will have better readability. After all, overusing ternary operators can make the code obscure and hard to understand.

In addition, Python also supports some other conditional expression writing styles, such as:

result = (False, True)[x > 0]


result = {True: 'positive', False: 'non-positive'}[x > 0]

However, these writing styles are not very readable, and beginners don't need to focus on them for now.

if name == "main"

You must have seen this strange conditional statement in Python code. What is it used for?

When a Python script is directly run, its __name__ variable will be assigned the value "__main__". When this script is imported by other Python programs, __name__ will be assigned the actual module name.

Taking advantage of this, we can define reusable functions and classes in the same .py file, and also write code that only runs when directly executed, thus achieving modular programming.

def add(a, b):
    return a + b

if __name__ == "__main__":
    print(add(1, 2))  # This code only executes when directly run

Now, other Python programs can import the some_module module like this:

import some_module

result = some_module.add(3, 4)
print(result) # Outputs 7

This programming pattern is widely used in Python projects. By splitting different functionalities into different modules, it can greatly improve the readability and maintainability of the code.

So, when you see if __name__ == "__main__":, don't be confused. Instead, learn to use it to write high-quality Python code.

Code Organization

Module Imports

If your Python project has multiple .py files, then you need to learn about Python's module import mechanism.

In Python, each .py file can serve as a module. Modules can import each other, using classes, functions, etc. defined by each other.

Suppose we have a utils.py module that defines a double function:

def double(x):
    return x * 2

To use the double function in another main.py file, you can import it like this:

import utils

result = utils.double(3)
print(result) # Outputs 6

You can also use the from...import... statement to import specific members from the module into the current namespace:

from utils import double

result = double(3) 

This import method looks more concise, but it also has some potential risks, such as naming conflicts. So I recommend using the standard import module import method.

In addition, Python also supports absolute imports and relative imports. Absolute imports search for modules from the beginning of the Python path, while relative imports start searching from the current path.

Relative imports are usually used to handle import relationships between different modules in the same package, and they are used as follows:

from . import utils


from .. import configs

Module import is a very important concept in Python programming, and there are quite a few details to pay attention to. However, as long as you understand the basic usage, you can freely organize your code structure in actual projects.

Reusable Modules

Speaking of modules, we have to mention some best practices for writing reusable modules.

First, each module should have a good __name__ and __doc__ string to explain the functionality of the module.

"""
my_module.py - This is a useful module that provides...
"""

__name__ = "my_module"

Second, don't put executable code directly at the top level of the module, as this will affect the reusability of the code. Instead, you can put this part of the code in an if __name__ == "__main__": conditional statement.

def my_function():
    ...

if __name__ == "__main__":
    # Execute some test or example code
    my_function(...)

Third, write good docstrings for the public interfaces in the module, which is important for other developers or for yourself to maintain the code later. You can use Python's documentation generation tool autodoc to automatically generate documentation.

def public_function(arg1, arg2):
    """
    This function is used for...

    Parameters:
    arg1 (int): Represents...
    arg2 (str): Represents...

    Returns:
    bool: Whether...
    """
    ...

Finally, define a good interface layer (API) for the module, exposing only the most core and commonly used parts to the outside. For some underlying implementation details, you can use naming with a single underscore _ at the beginning to make them private parts.

def public_api():
    ...


def _internal_util():
    ...

Through these best practices, you can write high-quality, reusable Python modules. However, the reusability of modules should also be based on the correctness of their internal implementation. So it's equally important to focus on unit testing and code quality.

In conclusion, I hope that through this blog post, you can grasp the essence of Python programming basics and lay a solid foundation for your subsequent programming journey. The road of programming is long and arduous, let's move forward together, continuously learning and improving!

Recommended Articles

More
Python syntax tricks

2024-11-09 01:05:01

Decoding Python's Magic
Explore the magical features of Python! From the curly brace magic of f-Strings to the clever use of list indexing, to the curious behavior of inf and nan, and elegant ways of writing conditional statements. Let's uncover the unique charm of Python, making your code more concise and efficient!

47

Basic Python Concepts

2024-11-08 13:06:01

Unveiling Python's Basic Concepts
In-depth analysis of basic concepts in Python such as generator functions, metaclasses, file operations, and ternary operators. Explore their principles, application scenarios, and considerations to help readers better understand and apply these important programming knowledge.

42

Python Programming Basics

2024-11-08 09:07:01

Python Programming Basics: From Beginner to Expert!
This article provides a detailed introduction to Python programming basics, including core concepts such as yield and generators, metaclasses, file operations, conditional expressions, module imports, and more. It offers practical code examples and best practice advice to help readers grow from Python beginners to programming experts.

36