Deep Dive into Python: Tuples, Sets, Object-Oriented Programming, File Operations, Exception Handling, and Generators

11. Tuples and Sets

In addition to lists and dictionaries, these two data structures are also very common:

1. Tuples (Immutable Sequences)

  • Defined using <span>()</span>, once the elements are set, they cannot be modified (immutable)
  • Suitable for storing fixed data (such as coordinates, configuration items)
# Define a tuple
point = (10, 20)  # Coordinates
user_info = ("Xiao Ming", 18, "Male")  # Multiple pieces of information

# Access elements (use index like a list)
print(point[0])  # 10

# Cannot modify! The following code will raise an error
# point[0] = 15  # TypeError

# Tuple unpacking (convenient for getting multiple values)
x, y = point
print(x, y)  # 10 20

2. Sets (Unordered, Unique Collections)

  • Defined using <span>{}</span> or <span>set()</span>, elements are unique (automatically deduplicated)
  • Suitable for deduplication, intersection / union, and other set operations
# Define a set (automatically deduplicated)
nums = {1, 2, 3, 2, 1}
print(nums)  # {1, 2, 3}

# Set operations
a = {1, 2, 3}
b = {3, 4, 5}
print(a & b)  # Intersection: {3}
print(a | b)  # Union: {1,2,3,4,5}
print(a - b)  # Difference: {1,2}

# Common operations
a.add(6)      # Add element: {1,2,3,6}
a.remove(3)   # Remove element: {1,2,6}

12. Basics of Object-Oriented Programming (Classes and Objects)

Python is an object-oriented language that encapsulates data and functionality using “classes”, which are closer to real-world abstractions:

1. Defining a Class (<span>class</span>)

# Define a "Person" class
class Person:
# Initialization method: automatically called when creating an object
    def __init__(self, name, age):
        self.name = name  # Instance attribute (data unique to each object)
        self.age = age

# Instance method: function within the class that operates on the object's data
    def greet(self):
        print(f"Hello, my name is {self.name}, I am {self.age} years old")

# Method to modify attributes
    def grow_up(self):
        self.age += 1  # Age +1

2. Creating Objects (Instantiation)

# Create two Person objects
p1 = Person("Xiao Ming", 18)
p2 = Person("Xiao Hong", 17)

# Call object methods
p1.greet()  # Hello, my name is Xiao Ming, I am 18 years old
p2.grow_up()
print(p2.age)  # 18 (age increased by 1)

3. Inheritance (Code Reuse)

A class can inherit attributes and methods from another class, reducing code duplication:

# Student class inherits from Person class
class Student(Person):
    def __init__(self, name, age, school):
# Call the parent class's initialization method
        super().__init__(name, age)
        self.school = school  # New attribute unique to students

# Override parent class method (custom behavior)
    def greet(self):
        print(f"I am {self.school}'s {self.name}, I am {self.age} years old")


# Create a student object
s = Student("Xiao Gang", 16, "Sunshine Middle School")
s.greet()  # I am Sunshine Middle School's Xiao Gang, I am 16 years old (calls the overridden method)
s.grow_up()  # Inherited method from parent class

13. Advanced File Operations

In addition to basic reading and writing, handle files in different scenarios:

1. Reading Large Files Line by Line

Reading a large file all at once can consume memory; it is suitable to read line by line:

with open("big_file.txt", "r", encoding="utf-8") as f:
    for line in f:  # Read line by line, memory-friendly
        print(line.strip())  # strip() removes newline characters

2. Writing Files (Overwrite / Append)

  • <span>"w"</span>: Overwrite (existing content will be cleared)
  • <span>"a"</span>: Append (add content at the end of the file)
# Overwrite
with open("test.txt", "w") as f:
    f.write("First line\n")

# Append
with open("test.txt", "a") as f:
    f.write("Second line\n")  # The file now has two lines of content

3. Handling CSV Files (Simple Tabular Data)

CSV is a comma-separated text file suitable for storing tabular data:

import csv  # Built-in csv module

# Write to CSV
with open("students.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerow(["Name", "Age", "School"])  # Header
    writer.writerow(["Xiao Ming", 18, "First Middle School"])
    writer.writerow(["Xiao Hong", 17, "Second Middle School"])

# Read from CSV
with open("students.csv", "r", encoding="utf-8") as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)  # Each row is a list

14. Advanced Exception Handling

In addition to the basic <span>try-except</span>, there are more flexible usages:

1. <span>else</span> Clause

Executed when the <span>try</span> block has no exceptions (different from <span>finally</span>):

try:
    num = int(input("Enter a number: "))
except ValueError:
    print("Input error")
else:
# Only executed if no exceptions
    print(f"You entered: {num}")

2. <span>finally</span> Clause

Executed regardless of whether there is an exception (suitable for resource cleanup):

file = None
try:
    file = open("test.txt", "r")
    content = file.read()
except FileNotFoundError:
    print("File does not exist")
finally:
# Ensure the file is closed regardless of errors
    if file:
        file.close()

3. Custom Exceptions

Define your own exception types based on business needs:

# Define a custom exception
class TooYoungError(Exception):
    def __init__(self, age):
        self.age = age

# Use custom exception
def check_age(age):
    if age < 18:
    # Raise exception
        raise TooYoungError(age)
    print("Age meets requirements")

try:
    check_age(15)
except TooYoungError as e:
    print(f"Error: Age {e.age} is too young, must be at least 18")

15. Generators (<span>yield</span>)

Generators are a special type of iterator, suitable for handling large amounts of data (generate and use on the fly, memory-efficient):

# Define a generator function (returns values using yield)
def generate_numbers(n):
    for i in range(n):
        yield i  # Returns a value each time called, pauses the function
        print(f"Generated {i}")  # Continues from here on the next call

# Use the generator
gen = generate_numbers(3)
print(next(gen))  # 0 (first call, executes up to yield)
print(next(gen))  # 1 (second call, continues from the last pause)
print(next(gen))  # 2
# Output:
# 0
# Generated 0
# 1
# Generated 1
# 2
# Generated 2

# Generators can be used directly in for loops
for num in generate_numbers(3):
    print(num)  # 0 1 2

Leave a Comment