Einführung
In diesem Tutorial werden wir untersuchen, wie man auf Attribute von Python-Objekten zugreift und diese modifiziert. Das Verständnis, wie man mit Objekteigenschaften arbeitet, ist eine grundlegende Fähigkeit für die Python-Programmierung. Am Ende dieses Labors werden Sie in der Lage sein, Objekte zu erstellen, auf ihre Attribute mit verschiedenen Methoden zuzugreifen und diese Attribute zu modifizieren, um das Objektverhalten zu ändern.
Python ist eine objektorientierte Programmiersprache, was bedeutet, dass alles in Python ein Objekt mit Eigenschaften und Methoden ist. Das Erlernen der Interaktion mit diesen Objekten ist für die Entwicklung effektiver Python-Anwendungen unerlässlich.
Erstellen einer einfachen Python-Klasse
Beginnen wir damit, zu verstehen, was Python-Klassen und -Objekte sind und wie man sie erstellt.
Was sind Klassen und Objekte?
In Python ist eine Klasse eine Blaupause für die Erstellung von Objekten. Objekte sind Instanzen von Klassen, die Folgendes enthalten:
- Attribute: Variablen, die Daten speichern
- Methoden: Funktionen, die Aktionen definieren, die das Objekt ausführen kann
Stellen Sie sich eine Klasse als Vorlage und ein Objekt als etwas vor, das aus dieser Vorlage erstellt wurde.
Erstellen Ihrer ersten Klasse
Erstellen wir eine einfache Person-Klasse mit einigen grundlegenden Attributen. Öffnen Sie den Code-Editor und erstellen Sie eine neue Datei namens person.py im Verzeichnis /home/labex/project:
## Define a Person class with name and age attributes
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"Hello, my name is {self.name} and I am {self.age} years old."
## Create a Person object
john = Person("John", 30)
## Print the object
print(john)
print(f"Type of john: {type(john)}")
Dieser Code definiert eine Person-Klasse mit zwei Attributen (name und age) und einer Methode (greet). Lassen Sie uns die Schlüsselkomponenten verstehen:
class Person:- Diese Zeile deklariert eine neue Klasse namensPerson__init__- Dies ist eine spezielle Methode, ein sogenannter Konstruktor, der ein neues Objekt initialisiert, wenn es erstellt wirdself- Dieser Parameter bezieht sich auf das Objekt, das erstellt oder manipuliert wirdself.name = name- Dies erstellt ein Attribut namensnamefür das Objekt und weist ihm den Wert zu, der an den Konstruktor übergeben wird
Führen wir nun diesen Code aus, um zu sehen, was passiert:
python3 /home/labex/project/person.py
Sie sollten eine Ausgabe ähnlich der folgenden sehen:
<__main__.Person object at 0x7f8b2c3d9d90>
Type of john: <class '__main__.Person'>
Diese Ausgabe zeigt uns, dass john ein Objekt der Person-Klasse ist. Die Hexadezimalzahl ist die Speicheradresse, an der das Objekt gespeichert ist.
Erstellen mehrerer Objekte
Wir können mehrere Objekte aus einer einzigen Klasse erstellen. Ändern wir unsere Datei person.py, um ein weiteres Person-Objekt zu erstellen:
## Define a Person class with name and age attributes
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"Hello, my name is {self.name} and I am {self.age} years old."
## Create two Person objects
john = Person("John", 30)
alice = Person("Alice", 25)
## Print information about both objects
print(f"First person: {john.name}, {john.age}")
print(f"Second person: {alice.name}, {alice.age}")
Führen Sie den aktualisierten Code aus:
python3 /home/labex/project/person.py
Sie sollten Folgendes sehen:
First person: John, 30
Second person: Alice, 25
Jetzt haben wir zwei verschiedene Person-Objekte erstellt, jedes mit seinen eigenen name- und age-Attributen.
Zugriff auf Objektattribute
Nachdem wir nun Objekte mit Attributen erstellt haben, wollen wir verschiedene Möglichkeiten kennenlernen, um auf diese Attribute zuzugreifen.
Verwendung der Punktnotation
Die gebräuchlichste Methode, um auf Objektattribute zuzugreifen, ist die Verwendung der Punktnotation: object.attribute.
Erstellen wir eine neue Datei namens access_attributes.py im Verzeichnis /home/labex/project:
class Person:
def __init__(self, name, age, job):
self.name = name
self.age = age
self.job = job
def greet(self):
return f"Hello, my name is {self.name} and I am {self.age} years old."
## Create a Person object
john = Person("John", 30, "Developer")
## Access attributes using dot notation
print(f"Name: {john.name}")
print(f"Age: {john.age}")
print(f"Job: {john.job}")
## Access and call a method
greeting = john.greet()
print(f"Greeting: {greeting}")
Führen Sie diesen Code aus:
python3 /home/labex/project/access_attributes.py
Sie sollten Folgendes sehen:
Name: John
Age: 30
Job: Developer
Greeting: Hello, my name is John and I am 30 years old.
Zugriff auf Attribute mithilfe von Variablen
Manchmal müssen Sie möglicherweise auf ein Attribut zugreifen, wenn Sie nur seinen Namen als Zeichenkette haben. Dies kann nützlich sein, wenn Sie mit dynamisch bestimmten Attributnamen arbeiten.
Ändern wir unsere Datei access_attributes.py:
class Person:
def __init__(self, name, age, job):
self.name = name
self.age = age
self.job = job
def greet(self):
return f"Hello, my name is {self.name} and I am {self.age} years old."
## Create a Person object
john = Person("John", 30, "Developer")
## List of attributes to access
attributes = ["name", "age", "job"]
## Access attributes using a loop and dot notation
print("Accessing attributes using dot notation:")
for attr in attributes:
if attr == "name":
print(f"Name: {john.name}")
elif attr == "age":
print(f"Age: {john.age}")
elif attr == "job":
print(f"Job: {john.job}")
## Call a method
greeting = john.greet()
print(f"Greeting: {greeting}")
Führen Sie den Code aus:
python3 /home/labex/project/access_attributes.py
Sie sollten Folgendes sehen:
Accessing attributes using dot notation:
Name: John
Age: 30
Job: Developer
Greeting: Hello, my name is John and I am 30 years old.
Das ist etwas umständlich. Im nächsten Schritt werden wir eine elegantere Methode zum dynamischen Zugriff auf Attribute kennenlernen.
Verwendung der Funktionen getattr() und setattr()
Python bietet eingebaute Funktionen, um dynamisch auf Objektattribute zuzugreifen und diese zu ändern. Diese sind besonders nützlich, wenn Sie mit Attributnamen arbeiten möchten, die erst zur Laufzeit bekannt sind.
Die Funktion getattr()
Die Funktion getattr() ermöglicht es Ihnen, auf ein Attribut zuzugreifen, indem Sie seinen Namen als Zeichenkette verwenden. Die Syntax lautet:
getattr(object, attribute_name, default_value)
object: Das Objekt, dessen Attribut Sie abrufen möchtenattribute_name: Eine Zeichenkette, die den Namen des Attributs enthältdefault_value: Ein optionaler Wert, der zurückgegeben wird, wenn das Attribut nicht existiert
Erstellen wir eine neue Datei namens dynamic_attributes.py im Verzeichnis /home/labex/project:
class Person:
def __init__(self, name, age, job):
self.name = name
self.age = age
self.job = job
def greet(self):
return f"Hello, my name is {self.name} and I am {self.age} years old."
## Create a Person object
john = Person("John", 30, "Developer")
## List of attributes to access
attributes = ["name", "age", "job", "address"]
## Access attributes using getattr()
print("Accessing attributes using getattr():")
for attr in attributes:
## The third parameter is the default value if the attribute doesn't exist
value = getattr(john, attr, "Not available")
print(f"{attr.capitalize()}: {value}")
## Call a method using getattr
greet_method = getattr(john, "greet")
greeting = greet_method()
print(f"Greeting: {greeting}")
Führen Sie diesen Code aus:
python3 /home/labex/project/dynamic_attributes.py
Sie sollten Folgendes sehen:
Accessing attributes using getattr():
Name: John
Age: 30
Job: Developer
Address: Not available
Greeting: Hello, my name is John and I am 30 years old.
Beachten Sie, dass getattr() für das Attribut address, das nicht existiert, unseren Standardwert "Not available" zurückgibt, anstatt einen Fehler auszulösen.
Die Funktion setattr()
Die Funktion setattr() ermöglicht es Ihnen, ein Attribut mithilfe seines Namens als Zeichenkette festzulegen. Die Syntax lautet:
setattr(object, attribute_name, value)
object: Das Objekt, dessen Attribut Sie festlegen möchtenattribute_name: Eine Zeichenkette, die den Namen des Attributs enthältvalue: Der Wert, der dem Attribut zugewiesen werden soll
Ändern wir unsere Datei dynamic_attributes.py, um Beispiele für die Verwendung von setattr() einzufügen:
class Person:
def __init__(self, name, age, job):
self.name = name
self.age = age
self.job = job
def greet(self):
return f"Hello, my name is {self.name} and I am {self.age} years old."
## Create a Person object
john = Person("John", 30, "Developer")
print("Original attributes:")
print(f"Name: {john.name}")
print(f"Age: {john.age}")
print(f"Job: {john.job}")
## Modify attributes using setattr()
print("\nModifying attributes using setattr():")
setattr(john, "name", "John Smith")
setattr(john, "age", 31)
setattr(john, "job", "Senior Developer")
## Add a new attribute using setattr()
setattr(john, "address", "123 Main St")
## Print the modified attributes
print("\nModified attributes:")
print(f"Name: {john.name}")
print(f"Age: {john.age}")
print(f"Job: {john.job}")
print(f"Address: {john.address}")
## Access attributes using getattr()
print("\nAccessing attributes using getattr():")
for attr in ["name", "age", "job", "address"]:
value = getattr(john, attr, "Not available")
print(f"{attr.capitalize()}: {value}")
Führen Sie den aktualisierten Code aus:
python3 /home/labex/project/dynamic_attributes.py
Sie sollten Folgendes sehen:
Original attributes:
Name: John
Age: 30
Job: Developer
Modifying attributes using setattr():
Modified attributes:
Name: John Smith
Age: 31
Job: Senior Developer
Address: 123 Main St
Accessing attributes using getattr():
Name: John Smith
Age: 31
Job: Senior Developer
Address: 123 Main St
Beachten Sie, dass wir in der Lage waren, bestehende Attribute zu ändern und auch ein völlig neues Attribut (address) hinzuzufügen, das in der Klasse nicht definiert war.
Praktisches Beispiel
Erstellen wir ein praktischeres Beispiel, in dem dynamischer Attributzugriff und -modifikation nützlich sind. Erstellen Sie eine Datei namens data_processor.py im Verzeichnis /home/labex/project:
class DataRecord:
def __init__(self):
## Start with no attributes
pass
## Create a function to process a dictionary into an object
def dict_to_object(data_dict):
record = DataRecord()
for key, value in data_dict.items():
setattr(record, key, value)
return record
## Sample data (could come from a database, API, etc.)
user_data = {
"user_id": 12345,
"username": "johndoe",
"email": "john@example.com",
"active": True,
"login_count": 27
}
## Convert the dictionary to an object
user = dict_to_object(user_data)
## Access the attributes
print(f"User ID: {user.user_id}")
print(f"Username: {user.username}")
print(f"Email: {user.email}")
print(f"Active: {user.active}")
print(f"Login Count: {user.login_count}")
## We can also add or modify attributes
setattr(user, "last_login", "2023-09-15")
setattr(user, "login_count", 28)
print("\nAfter modifications:")
print(f"Login Count: {user.login_count}")
print(f"Last Login: {user.last_login}")
## We can also access all attributes dynamically
print("\nAll attributes:")
for attr in ["user_id", "username", "email", "active", "login_count", "last_login"]:
value = getattr(user, attr, None)
print(f"{attr}: {value}")
Führen Sie diesen Code aus:
python3 /home/labex/project/data_processor.py
Sie sollten Folgendes sehen:
User ID: 12345
Username: johndoe
Email: john@example.com
Active: True
Login Count: 27
After modifications:
Login Count: 28
Last Login: 2023-09-15
All attributes:
user_id: 12345
username: johndoe
email: john@example.com
active: True
login_count: 28
last_login: 2023-09-15
Dieses Beispiel zeigt, wie Sie Daten aus einem Dictionary (das aus einer Datenbank, API oder Datei stammen kann) in ein Objekt konvertieren und dann dynamisch auf seine Attribute zugreifen oder diese ändern können.
Praktische Anwendungen von Objektattributen
Nachdem wir nun verstanden haben, wie man auf Objektattribute zugreift und diese ändert, wollen wir einige praktische Anwendungen dieser Konzepte untersuchen. Wir erstellen ein einfaches Bestandsverwaltungssystem, um zu demonstrieren, wie Objektattribute in realen Anwendungen verwendet werden können.
Erstellen eines Inventarsystems
Erstellen wir eine Datei namens inventory.py im Verzeichnis /home/labex/project:
class Product:
def __init__(self, product_id, name, price, quantity):
self.product_id = product_id
self.name = name
self.price = price
self.quantity = quantity
def total_value(self):
return self.price * self.quantity
def display_info(self):
return f"Product: {self.name} (ID: {self.product_id})\nPrice: ${self.price:.2f}\nQuantity: {self.quantity}\nTotal Value: ${self.total_value():.2f}"
class Inventory:
def __init__(self):
self.products = {}
def add_product(self, product):
self.products[product.product_id] = product
print(f"Added: {product.name}")
def remove_product(self, product_id):
if product_id in self.products:
product = self.products.pop(product_id)
print(f"Removed: {product.name}")
return True
print(f"Product with ID {product_id} not found.")
return False
def update_quantity(self, product_id, new_quantity):
if product_id in self.products:
product = self.products[product_id]
old_quantity = product.quantity
product.quantity = new_quantity
print(f"Updated quantity of {product.name} from {old_quantity} to {new_quantity}")
return True
print(f"Product with ID {product_id} not found.")
return False
def display_inventory(self):
if not self.products:
print("Inventory is empty.")
return
print("\n===== Current Inventory =====")
total_value = 0
for product in self.products.values():
print(f"\n{product.display_info()}")
total_value += product.total_value()
print(f"\nTotal Inventory Value: ${total_value:.2f}")
print("============================")
## Create an inventory
inventory = Inventory()
## Create some products
laptop = Product(1, "Laptop", 999.99, 5)
phone = Product(2, "Smartphone", 499.95, 10)
headphones = Product(3, "Wireless Headphones", 149.99, 15)
## Add products to inventory
inventory.add_product(laptop)
inventory.add_product(phone)
inventory.add_product(headphones)
## Display the inventory
inventory.display_inventory()
## Update quantities
inventory.update_quantity(1, 7) ## Increase laptop quantity
inventory.update_quantity(3, 10) ## Decrease headphones quantity
## Display the updated inventory
inventory.display_inventory()
## Remove a product
inventory.remove_product(2) ## Remove smartphones
## Display the final inventory
inventory.display_inventory()
Führen Sie diesen Code aus:
python3 /home/labex/project/inventory.py
Sie sollten eine Ausgabe ähnlich der folgenden sehen:
Added: Laptop
Added: Smartphone
Added: Wireless Headphones
===== Current Inventory =====
Product: Laptop (ID: 1)
Price: $999.99
Quantity: 5
Total Value: $4999.95
Product: Smartphone (ID: 2)
Price: $499.95
Quantity: 10
Total Value: $4999.50
Product: Wireless Headphones (ID: 3)
Price: $149.99
Quantity: 15
Total Value: $2249.85
Total Inventory Value: $12249.30
============================
Updated quantity of Laptop from 5 to 7
Updated quantity of Wireless Headphones from 15 to 10
===== Current Inventory =====
Product: Laptop (ID: 1)
Price: $999.99
Quantity: 7
Total Value: $6999.93
Product: Smartphone (ID: 2)
Price: $499.95
Quantity: 10
Total Value: $4999.50
Product: Wireless Headphones (ID: 3)
Price: $149.99
Quantity: 10
Total Value: $1499.90
Total Inventory Value: $13499.33
============================
Removed: Smartphone
===== Current Inventory =====
Product: Laptop (ID: 1)
Price: $999.99
Quantity: 7
Total Value: $6999.93
Product: Wireless Headphones (ID: 3)
Price: $149.99
Quantity: 10
Total Value: $1499.90
Total Inventory Value: $8499.83
============================
Arbeiten mit dynamischen Attributen
Erweitern wir unser Inventarsystem, um dynamische Attribute mithilfe von getattr() und setattr() zu verarbeiten. Erstellen Sie eine Datei namens enhanced_inventory.py im Verzeichnis /home/labex/project:
class Product:
def __init__(self, product_id, name, price, quantity, **kwargs):
self.product_id = product_id
self.name = name
self.price = price
self.quantity = quantity
## Add any additional attributes provided
for key, value in kwargs.items():
setattr(self, key, value)
def total_value(self):
return self.price * self.quantity
def display_info(self):
result = [f"Product: {self.name} (ID: {self.product_id})",
f"Price: ${self.price:.2f}",
f"Quantity: {self.quantity}",
f"Total Value: ${self.total_value():.2f}"]
## Display additional attributes
standard_attrs = {'product_id', 'name', 'price', 'quantity'}
for attr in dir(self):
if not attr.startswith('__') and not callable(getattr(self, attr)) and attr not in standard_attrs:
value = getattr(self, attr)
result.append(f"{attr.replace('_', ' ').title()}: {value}")
return '\n'.join(result)
class Inventory:
def __init__(self):
self.products = {}
def add_product(self, product):
self.products[product.product_id] = product
print(f"Added: {product.name}")
def update_attribute(self, product_id, attribute, value):
if product_id in self.products:
product = self.products[product_id]
old_value = getattr(product, attribute, None)
setattr(product, attribute, value)
print(f"Updated {attribute} of {product.name} from {old_value} to {value}")
return True
print(f"Product with ID {product_id} not found.")
return False
def display_inventory(self):
if not self.products:
print("Inventory is empty.")
return
print("\n===== Current Inventory =====")
total_value = 0
for product in self.products.values():
print(f"\n{product.display_info()}")
total_value += product.total_value()
print(f"\nTotal Inventory Value: ${total_value:.2f}")
print("============================")
## Create an inventory
inventory = Inventory()
## Create products with additional attributes
laptop = Product(1, "Laptop", 999.99, 5, brand="TechPro", model="X5", color="Silver", warranty_years=2)
phone = Product(2, "Smartphone", 499.95, 10, brand="MobiCom", model="Galaxy", color="Black", has_5g=True)
headphones = Product(3, "Wireless Headphones", 149.99, 15, brand="AudioMax", battery_life_hours=20, is_noise_cancelling=True)
## Add products to inventory
inventory.add_product(laptop)
inventory.add_product(phone)
inventory.add_product(headphones)
## Display the inventory
inventory.display_inventory()
## Update a standard attribute
inventory.update_attribute(1, "price", 1099.99)
## Update a custom attribute
inventory.update_attribute(3, "battery_life_hours", 25)
## Add a new attribute to an existing product
inventory.update_attribute(2, "water_resistant", True)
## Display the updated inventory
inventory.display_inventory()
Führen Sie diesen Code aus:
python3 /home/labex/project/enhanced_inventory.py
Sie sollten eine Ausgabe ähnlich der folgenden sehen:
Added: Laptop
Added: Smartphone
Added: Wireless Headphones
===== Current Inventory =====
Product: Laptop (ID: 1)
Price: $999.99
Quantity: 5
Total Value: $4999.95
Brand: TechPro
Color: Silver
Model: X5
Warranty Years: 2
Product: Smartphone (ID: 2)
Price: $499.95
Quantity: 10
Total Value: $4999.50
Brand: MobiCom
Color: Black
Has 5g: True
Model: Galaxy
Product: Wireless Headphones (ID: 3)
Price: $149.99
Quantity: 15
Total Value: $2249.85
Battery Life Hours: 20
Brand: AudioMax
Is Noise Cancelling: True
Total Inventory Value: $12249.30
============================
Updated price of Laptop from 999.99 to 1099.99
Updated battery_life_hours of Wireless Headphones from 20 to 25
Updated water_resistant of Smartphone from None to True
===== Current Inventory =====
Product: Laptop (ID: 1)
Price: $1099.99
Quantity: 5
Total Value: $5499.95
Brand: TechPro
Color: Silver
Model: X5
Warranty Years: 2
Product: Smartphone (ID: 2)
Price: $499.95
Quantity: 10
Total Value: $4999.50
Brand: MobiCom
Color: Black
Has 5g: True
Model: Galaxy
Water Resistant: True
Product: Wireless Headphones (ID: 3)
Price: $149.99
Quantity: 15
Total Value: $2249.85
Battery Life Hours: 25
Brand: AudioMax
Is Noise Cancelling: True
Total Inventory Value: $12749.30
============================
In diesem erweiterten Inventarsystem haben wir demonstriert, wie man getattr() und setattr() in einer komplexeren Anwendung verwendet:
- Die Klasse
Productakzeptiert zusätzliche Attribute über**kwargsund setzt diese dynamisch mitsetattr() - Die Methode
display_info()verwendetgetattr(), um alle Attribute des Produkts anzuzeigen - Die Methode
update_attribute()in der KlasseInventoryverwendetgetattr(), um den aktuellen Wert abzurufen, undsetattr(), um ihn zu aktualisieren
Dieser Ansatz bietet eine große Flexibilität und ermöglicht es uns, Produkte mit unterschiedlichen Attributen zu verarbeiten, ohne die Klassendefinition zu ändern.
Zusammenfassung
In diesem Lab haben Sie gelernt, wie man mit Python-Objektattributen arbeitet, was eine grundlegende Fähigkeit für effektives Python-Programmieren ist. Hier ist eine Zusammenfassung dessen, was Sie erreicht haben:
Erstellen von Klassen und Objekten: Sie haben gelernt, wie man Python-Klassen mit Attributen und Methoden erstellt und wie man Objekte aus diesen Klassen instanziiert.
Zugriff auf Objektattribute: Sie haben verschiedene Möglichkeiten erkundet, um auf Objektattribute zuzugreifen, einschließlich:
- Verwendung der Punktschreibweise (
object.attribute) - Verwendung der Funktion
getattr()für dynamischen Zugriff
- Verwendung der Punktschreibweise (
Ändern von Objektattributen: Sie haben gelernt, wie man Objektattribute ändert, indem man:
- Direkte Zuweisung mit Punktschreibweise (
object.attribute = value) - Die Funktion
setattr()für dynamische Modifikation
- Direkte Zuweisung mit Punktschreibweise (
Praktische Anwendungen: Sie haben diese Konzepte angewendet, um praktische Anwendungen zu erstellen:
- Ein einfaches Bestandsverwaltungssystem
- Ein erweitertes System mit dynamischer Attributverarbeitung
Diese Fähigkeiten helfen Ihnen, flexiblere und leistungsfähigere Python-Anwendungen zu erstellen. Das Verständnis, wie man mit Objektattributen arbeitet, ist für Aufgaben wie Datenverarbeitung, Konfigurationsmanagement und die Erstellung erweiterbarer Softwaresysteme unerlässlich.
Für weitere Übungen sollten Sie in Erwägung ziehen, das Bestandsverwaltungssystem mit zusätzlichen Funktionen zu erweitern, wie z. B.:
- Filtern von Produkten basierend auf Attributen
- Sortieren von Produkten nach verschiedenen Kriterien
- Hinzufügen von Validierung für Attributmodifikationen
- Implementierung der Serialisierung zum Speichern und Laden von Bestandsdaten



