没有系统学过python,所以跟着quick tutorial捋一遍。 只记录自己不太熟悉的内容。
文章目录
Recursion 递归
-
Recursive factorial function
def factorial(n:int): # n! if n == 0 or n == 1: return 1 else: return n * factorial (n-1)
-
The fibonacci function
def fibonacci(n): if n == 0 or n == 1: return n else: return fibonacci(n-1) + fibonacci(n-2)
-
Find a Power Recursively
def find_power(a,b): if b == 0: return 1 else: return a * find_power(a, b-1)
Exception Handling
-
try
/except
index = int(input("Enter the index: ")) try: my_list = [1, 2, 3, 4] print(my_list[index]) except: print("Please enter a valid index.") ```
-
catch a specific type of exception
try: <code_that_may_raise_an_exception> except <exception_type>: <code_to_handle_an_exception_if_it_occurs>
list of common exception types:
Exception Type Corresponding reason ZeroDivisionError raised when the second argument of a division or modulo operation is zero. IndexError raised when we try to use an invalid index to access an element of a sequence. KeyError raised when we try to access a key-value pair that doesn’t exist because the key is not in the dictionary. NameError raised when we use a variable that has not been defined previously. RecursionError raised when the interpreter detects that the maximum recursion depth is exceeded. This usually occurs when the process never reaches the base case. -
Assign a name to the exceptioin object
try: <code_that_may_raise_an_exception> except <exception_type> as <name>: <code_to_handle_an_exception_if_it_occurs>
e.g.
index = int(input("Enter the index: ")) try: my_list = [1, 2, 3, 4] print(my_list[index]) except IndexError as e: print("Exception raised:", e)
-
try
/except
/else
try: <code_that_may_raise_an_exception> except: <code_to_handle_an_exception_if_it_occurs> else: <code_that_only_runs_if_no_exception_in_try>
e.g.
a = int(input("Enter a: ")) b = int(input("Enter b: ")) try: division = a / b print(division) except ZeroDivisionError as err: print("Please enter valid values.", err) else: print("Both values were valid.")
-
try
/except
/else
/finally
a = int(input("Enter a: ")) b = int(input("Enter b: ")) try: division = a / b print(division) except ZeroDivisionError as err: print("Please enter valid values.", err) else: print("Both values were valid.") finally: print("Finally!")
Object-Oriented Programming
class <className>:
<class_attribute_name> = <value>
def __init__(self,<param1>, <param2>, ...):
self.<attr1> = <param1>
self.<attr2> = <param2>
.
.
.
# As many attributes as needed
def <method_name>(self, <param1>, ...):
<code>
# As many methods as needed
- create an instance
my_dog = Dog("Nora", 10)
- remove an instance attribute
del <object_variable>.<attribute>
- delete an instance
del my_dog
- public vs. Non-public attributes
Use one leading underscore only for non-public methods and instance variables. source
e.g.class Dog: def __init__(self, name, age): self.name = name # Public attribute self._age = age # Non-Public attribute
- Class Attributes: shared by all instances of the class.
💡 Tip: Usually, they are written before the__init__
method.
e.g.
Get a class attributeclass Dog: # Class attributes kingdom = "Animalia" species = "Canis lupus" def __init__(self, name, age): self.name = name self.age = age
<class_name>.<attribute>
e.g.Dog.kingdom
😀 Tip: You can use this syntax within the class as well; we can use similar methods for updating or deleting the class attribute
Properties, Getters and Setters
Getters and setters are methods that we can define to get and set the value of an instance attribute, respectively. They work as intermediaries to “protect” the attributes from direct changes.
- To define a property, we write a method with this syntax:
This method will act as a getter, so it will be called when we try to access the value of the attribute.@property def <property_name>(self): return self.<attribute>
- define a setter:
@<property_name>.setter def <property_name>(self, <param>): self.<attribute> = <param>
- deleter to delete the attribute
@<property_name>.deleter def <property_name>(self): del self.<attribute>
💡 Tip: you can write any code that you need in these methods to get, set, and delete an attribute. It is recommended to keep them as simple as possible.
e.g.
>>> class Dog:
def __init__(self, name):
self._name = name
@property
def name(self):
print("Calling getter")
return self._name
@name.setter
def name(self, new_name):
print("Calling setter")
self._name = new_name
@name.deleter
def name(self):
print("Calling deleter")
del self._name
>>> my_dog = Dog("Nora")
>>> my_dog.name
Calling getter
'Nora'
>>> my_dog.name = "Norita"
Calling setter
>>> my_dog.name
Calling getter
'Norita'
>>> del my_dog.name
Calling deleter
Files
- Read
r
e.g.with open("<file_path>", "r") as <file_var>: <code>
💡 Tip: that’s right! We can iterate over the lines of the file using a for loop. The file path can be relative to the Python script that we are running or it can be an absolute path.with open("famous_quotes.txt") as file: for line in file: print(line)
- Write
w
: to replace the content completely
e.g.words = ["Amazing", "Green", "Python", "Code"] with open("famous_quotes.txt", "w") as file: for word in words: file.write(word + "\n")
- Append
a
: append the content
e.g.words = ["Amazing", "Green", "Python", "Code"] with open("famous_quotes.txt", "a") as file: for word in words: file.write(word + "\n")
- Delete a file : use the
os
module. Remember to check with a conditional if the file exists before calling theremove()
e.g.import os if os.path.exists("<file_path>"): os.remove("<file_path>") else: <code>
import os if os.path.exists("famous_quotes.txt"): os.remove("famous_quotes.txt") else: print("This file doesn't exist")
List and Dictionary Comprehension
-
List comprehension
[<value_to_include> for <var> in <sequence>] [<value_to_include> for <var1> in <sequence1> for <var2> in <sequence2>] [<value_to_include> for <var> in <sequence> if <condition>] [<value> for <var1> in <sequence1> for <var2> in <sequence2> if <condition>]
💡 Tip: you should only use them when they do not make your code more difficult to read and understand.
>>> [i for i in range(4, 15)] [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] >>> [chr(i) for i in range(67, 80)] ['C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O'] >>> [i**3 for i in range(2, 5)] [8, 27, 64] >>> [i + j for i in range(5, 8) for j in range(3, 6)] [8, 9, 10, 9, 10, 11, 10, 11, 12] >>> [k for k in range(3, 35) if k % 2 == 0] [4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34] >>> [i * j for i in range(2, 6) for j in range(3, 7) if i % j == 0] [9, 16, 25]
-
List comprehensions vs. Generator Expressions
List comprehensions are defined with square brackets
[]
. This is different from generator expressions, which are defined with parentheses()
. They look similar but they are quite different- List comprehensions generate the entire sequence at once and store it in memory.
- Generator expressions yield the elements one at a time when they are requested.
We can check this with
sys
module.>>> import sys >>> sys.getsizeof([i for i in range(500)]) 2132 >>> sys.getsizeof((i for i in range(500))) 56
-
Dictionary Comprehension
{<key_value>: <value> for <var> in <sequence>} {<key_value>: <value> for <var> in <sequence> if <condition>}
e.g.
>>> {num: num**3 for num in range(3, 15)} {3: 27, 4: 64, 5: 125, 6: 216, 7: 343, 8: 512, 9: 729, 10: 1000, 11: 1331, 12: 1728, 13: 2197, 14: 2744} >>> {x: x + y for x in range(4, 8) for y in range(3, 7)} {4: 10, 5: 11, 6: 12, 7: 13} # with conditions >>> grades = {"Nora": 78, "Gino": 100, "Talina": 56, "Elizabeth": 45, "Lulu": 67} >>> approved_students = {student: grade for (student, grade) in grades.items() if grade >= 60} >>> approved_students {'Nora': 78, 'Gino': 100, 'Lulu': 67}
Tricks
- get the indices of an Numpy array.
idx = list(classes).index(var) idx = np.where(classes == var)