Main Topics Covered:
*args and **kwargs
Magic Variables.The
__init__.py
files.super( ).__init__ use case
type() versus isinstance()
to check data types.Private attributes - getters and setters
Create a simple x-y plot.
Static methods review.
Name file dynamically with extension :
.json
Unittest
Notes : Test accessibility to a private attribute and more.
*args and **kwargs
Magic Variables:
In Python, args
and kwargs
are special parameters that can be used in function definitions to allow for a variable number of arguments to be passed to the function.
args
stands for "arguments" and is used to pass a variable number of non-keyword arguments to a function. When args
is used in a function definition, it allows the function to accept any number of positional arguments. These arguments are passed as a tuple.
For example, consider the following function:
def foo(*args):
for arg in args:
print(arg)
This function can accept any number of arguments and will print each argument on a new line.
This function can accept any number of arguments and will print each argument on a new line.
Note: In Python, keyword arguments (
kwargs
) are typically specified using the syntaxparameter_name=value
when calling a function.
kwargs
stands for "keyword arguments" and is used to pass a variable number of keyword arguments to a function. When kwargs
is used in a function definition, it allows the function to accept any number of keyword arguments. These arguments are passed as a dictionary.
For example, consider the following function:
def my_kwargs(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
my_kwargs(name="shaza", email="shaza.aly@gmail.com")
In computer programming, a keyword argument is a way of passing arguments to a function by specifying the argument name along with its value. This is in contrast to positional arguments, where the order of arguments is used to determine their value.
Here's an example of a function that takes both positional and keyword arguments in
def greet(name, greeting="Hello"):
print(greeting + ", " + name + "!")
In this example, name
is a required positional argument, while greeting
is an optional keyword argument with a default value of "Hello"
.
The __init__.py
files: Python Package
The __init__.py
file is a special file in Python that is used to mark a directory as a Python package. It can contain initialization code for the package, or it can be an empty file.
Here is an example of a __init__.py
file:
# __init__.py
def init():
print("This is the __init__.py file.")
if __name__ == "__main__":
init()
This file will print the following message when it is imported:
This is the __init__.py file.
Class Attribute review example:
Private attributes, getters and setters:
super
is a built-in function in Python that is used to call a method in a parent class. It is commonly used in inheritance to call a method in a parent class from a subclass.
type()
and isinstance()
are both built-in Python functions that can be used to check the type of an object. However, they have different use cases.
use isinstance()
when checking the type of an object if you want to allow subclasses. Using type()
doesn't take into account subclasses.
Here's an example where isinstance()
returns True
but type()
returns False
:
use of {id(self)} in string representation :
In Python, __str__
is a special method that is used to define the string representation of an object. It is called by the str()
function and by the print()
function when an object is passed as an argument.
Here is an example of how to define __str__
for a simple class:
class MyClass:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"MyClass(x={self.x}, y={self.y})"
Create a simple x-y plot:
for i in range(5):
print("y")
for j in range(5):
print("x", end="")
Note that the print
function automatically adds a newline character at the end of each line, unless you specify a different value for the end
parameter. In this case, the end
parameter is set to an empty string for the second for
loop, which prevents the newline character from being printed.
Static Methods:
In Python, a static method is a method that belongs to a class rather than an instance of the class. Static methods are used when you have a function that is related to a class, but doesn't need to access any instance-specific data.
To define a static method in Python, you use the @staticmethod
decorator before the method definition. Here's an example:
class MyClass:
@
staticmethod
def my_static_method(arg1, arg2):
# do something with arg1 and arg2
return result
In this example, we define a MyClass
class with a static method my_static_method
. The @staticmethod
decorator tells Python that this method is a static method, rather than an instance method.
Static methods can be called on the class itself, rather than on an instance of the class. Here's an example of how to call the
my_static_method
static method:
result = MyClass.my_static_method(arg1, arg2)
Name file dynamically with extension : .json
The expression cls.__name__
is a Python expression that returns the name of the class that cls
refers to. For example, if we have a class called MyClass
, then the expression MyClass.__name__
will return the string 'MyClass'
.
The expression cls.__name__
can be used inside a class method to get the name of the class that the method belongs to. For example, the following code defines a class method called message
that prints the name of the class:
class MyClass:
@classmethod
def message(cls):
print(cls.__name__)
MyClass.message()
to create the filename with the .json
extension. cls.__name__
concatenate the name of the class with the .json
extension to create the filename. This approach works because cls.__name__
returns the name of the class as a string.
example output : MyClass.json
How to correctly call a static method?
To call a class static method inside a class method, you need to use the class name to refer to the static method. For example,
Note:
The main difference between a static method and a class method is that a static method does not need to be called on an instance of the class, while a class method needs to be called on an instance of the class, so it needs to be defined as a class method.
Unittest Notes:
Rabid guide:
A step-by-step guide to writing a unit test using the Python unittest module, with an example:
1. Import the unittest module: The first step is to import the unittest module, which provides the framework for writing and running unit tests. Here's an example:
```
import unittest
```
2. Define the test case class: Next, define a test case class that inherits from the unittest.TestCase class. This class will contain one or more test methods that exercise the code being tested. Here's an example:
```
class TestMyCode(unittest.TestCase):
def test_my_function(self):
# Test code goes here
```
3. Write the test method: Inside the test case class, write a test method that exercises the code being tested and verifies the expected behavior. Use the various assert methods provided by the unittest.TestCase class to check that the output of the code matches the expected result. Here's an example:
```
class TestMyCode(unittest.TestCase):
def test_my_function(self):
result = my_function(2, 3)
self.assertEqual(result, 5)
```
4. Run the test case: To run the test case, create an instance of the test case class and call the unittest.main() method. This will run all of the test methods in the class and report any failures. Here's an example:
```
if __name__ == '__main__':
unittest.main()
```
5. Check the test results: After running the tests, check the test results to ensure that all tests passed and that there were no errors or failures. If a test failed, review the test code and the code being tested to identify the source of the problem.
Here's a complete example that puts all of these steps together:
```
import unittest
def my_function(x, y):
return x + y
class TestMyCode(unittest.TestCase):
def test_my_function(self):
result = my_function(2, 3)
self.assertEqual(result, 5)
if __name__ == '__main__':
unittest.main()
```
In this example, we define a simple function `my_function` that adds two numbers together. We then define a test case class `TestMyCode` that contains one test method `test_my_function` that exercises the `my_function` code and verifies that it returns the expected result. Finally, we run the test case using the `unittest.main()` method and check the results to ensure that all tests passed.
Notes to consider:
In
unittest
If we are trying to test accessibility to a private attribute eg.width
of theShape
objects1
. This will raise anAttributeError
exception, because the private attribute is not accessible from outside the class. TheassertRaises()
method will catch this exception and the test will pass.Example:
with self.assertRaises(AttributeError):
width = r1.width
If we were to remove the
with
block, the code would try to access the private attributewidth
directly. This would cause theAttributeError
exception to be raised, but the test would fail.If Python cannot find the
models.moduleName
module. This could be because themodels
directory is not in the same directory as thetest_module.py
file, or because themodels
directory does not contain an__init__.py
file.Here's an example of how you can structure your directory to make sure the import statement works:
- my_program/ - models/ - __init__.py - rectangle.py - tests/ - test_models/ - __init__.py - test_rectangle.py - main.py
In this example, the
models
directory contains an__init__.py
file, which makes it a Python package. Therectangle.py
file contains the definition of theRectangle
class.The
tests
directory also contains an__init__.py
file, which makes it a Python package. Thetest_models
subdirectory contains thetest_rectangle.py
file, which contains the test case for theRectangle
class.To import the
Rectangle
class intest_rectangle.py
, you would use the following import statement:from models.rectangle import Rectangle
Resources : Slack PLD Pseudocode