Module 1 Examples -Variable type 2, Object oriented beginner - class & Ex amp le -Access restrictions -Inheritance polymorphism -Get object instance information (property method) -Instance properties vs class properties 3, Object oriented advanced - __slots__ -
- For instance
#!/usr/bin/env python3 # -*- coding: utf-8 -*- ' a test module ' # You can use modulename. Doc to access __author__ = 'Michael Liao' # You can access it with modulename import sys def test(): args = sys.argv if len(args)==1: print('Hello, world!') elif len(args)==2: print('Hello, %s!' % args) else: print('Too many arguments!') if __name__=='__main__': # When executing this script on the command line, the special variable "name" will be set to "main". When importing other modules, if judgment will be invalid test()
- Variable type:
__xxx: special variables. Special variables in a class can be accessed directly,
_xxx, zhuu xxx: such a function or variable is called "private" and should not be directly drunk, such as "abc"
This private variable or function should not be referenced. What are their functions?
def _private_1(name): return 'Hello, %s' % name def _private_2(name): return 'Hi, %s' % name def greeting(name): if len(name) > 3: return _private_1(name) else: return _private_2(name)
When calling greeting, use internal logic to hide private, so that calling greeting does not care about the details of its internal private function, and its function is "code encapsulation and abstraction"
2, Object oriented beginner
class Student(object): pass
- Compared with ordinary methods, the internal function, the first parameter is always' self ', which means that the created instance itself, and other uses are the same
- Class & instance (data encapsulation)
# Advantages 1. From the external perspective, students only need to provide name and age for instantiation. About how to print, it has been encapsulated into the internal class. It's easy to call, but I don't know the internal details # Advantage 2: you can add more methods to the Student class class Student(object): def __ini__(self, name, score): # Every time a class is instantiated, the init method is called once self.name = name self.score = score def print_score(self): print("%s, %s" % (self.name, self.score)) bart = Student("alex", 50) bart.print_score() //Since the corresponding data can be accessed within the instance itself, it's unnecessary to write the print score outside //Examples of errors are as follows: class Student(object): def __ini__(self, name, score): self.name = name self.score = score bart = Student("alex", 50) def print_score(std): print('%s: %s' % (std.name, std.score)) print_score(bart)
# 1. In order to avoid external code modifying the name and score of the instance at will, use the method of "naming" to restrict the direct access of the instance to the attribute, and accessing Bart directly from the outside will report an error # 2. What if you want to access or modify? ——Method to get # 3. If I have two attributes, one is [name], and the other is [name], what do these two attributes mean? # -_name is an instance variable that can be accessed externally, but it warns you not to access it at will # -The instance variable "name" cannot be accessed externally, but the python interpreter will change the double underlined variable to "student" name, so it can be accessed externally # 4. Then bart.name = "alex" can be modified directly. Why write a method to modify it? Isn't it a waste? # Answer: in the method, parameters can be checked to avoid invalid parameter passing in class Student(object): def __init__(self, name, score): self.__name = name self.__score = score def print_score(self): print('%s: %s' % (self.__name, self.__score)) def get_name(self): return self.__name def set_name(self, name): if len(name) > 100 or len(name) < 0: raise ValueError('bad name len') else: self.__name = name
- Inheritance and polymorphism
# 1. Inheritance: the subclass will inherit all the methods and functions of the parent class, and the subclass can continue to extend (overwrite) the methods of the parent class # 2. Polymorphism: for how to understand polymorphism, please refer to https://www.liaoxuefeng.com/wiki/1016959663602400/1017497232674368 # 3. A class is a data type, such as list, dict, str, etc class Animal(object): def run(self): print("animal can run!") class Dog(Animal): def run(self): print("Dog is Running") class Cat(Animal): print("Cat is Running") dog = Dog() dog.run() # polymorphic a = list() b = Animal() c = Dog() isinstance(a, list) isinstance(b, Animal) isinstance(c, Dog) isinstance(c, Animal) # Results are all True # Where is polymorphism good? def run_twice(animal): animal.run() animal.run() >>>run_twice(Animal()) "animal can run!" "animal can run!" >>>run_twice(Dog()) "Dog is Running" "Dog is Running" >>>run_twice(Cat()) "Cat is Running" "Cat is Running" # Summarize the benefits of polymorphism # 1. When a function needs to pass in Dog, Cat, Tortoise... Only need to accept the type of Animal, because they are all Animal # 2. So: any type passed in by the function (run twice), as long as it is an animal class or subclass, will automatically call the run() method of the opportunity type, which is the meaning of polymorphism # 3. Open to extension: allow to add new Animal subclass: # 4. Close to modification: it is not necessary to modify functions such as run ﹐ two(), which depend on the Animal type
- Get object (instance) information
# 1. Use type() # Get type information of object (instance) # 2. Use isinstance() # Judge whether an instance is a type # 3. Use dir() # Returns all properties and methods of an object # 4. hasattr(obj, 'x'), setattr(obj, 'y', 19), getattr(obj, 'y') >>>type('stringexample') >>>type(Dog()) >>>type(123) >>>def fn(): >>> pass >>>type(fn) == types.FunctionType >>>type(abs) == types.BuiltinFunctionType >>>type(lambda x: x*2) == types.LambdaType >>>type((x for x in range(10)))==types.GeneratorType # isinstance, assuming that the inheritance relationship is object - > animal - > dog - > husky >>> isinstance(h, Animal) >>> isinstance('a', str) >>> isinstance(b'a', bytes) >>> isinstance((1, 2, 3), (list, tuple)) // Is it a list or a tuple >>> dir('abc') ['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill'] >>> len('abc') == 'abc'.__len__() // The len() method is actually the call object's len() method, two equivalent # Property and method testing of objects >>> class MyObject(object): ... def __init__(self): ... self.x = 9 ... def power(self): ... return self.x * self.x ... >>> obj = MyObject() >>> hasattr(obj, 'x') # Whether there is attribute 'x' >>> setattr(obj, 'y', 19) # Set property 'y' to 9 >>> getattr(obj, 'y', 100) # Get the 'y' attribute value of obj object. If not, it defaults to 100 >>> obj.y 19
- Instance properties vs class properties
# 1. python is a dynamic language. According to an instance created by a class, you can bind attributes at will. The way to bind attributes to an instance is through the instance variable, or through the self attribute # 2. Instance properties will override class properties. Do not use the same name for instance properties and class properties class Student(object): def __init__(self, name): self.name = name s = Student('Bob') s.score = 90 # How to bind properties to the Student class? class Student(object): name = "Student" # Class properties are classified as all, but all instances of them are accessible >>> s = Student() >>> print(s.name) >>> print(Student.name) # If it is not a class property, this will report an error Student
3, Object oriented advanced
# 1. Bind method to instance through MethodType # 2. Use dynamic method to bind class # 3. Limit the attributes that an instance can add by defining "slots" in the class # 4. Slots are only valid for the current class, but not for its subclass. If a subclass also has slots, the limit of its subclass is the sum of subclass + parent class class Student(object): pass s = Student() s.name = "Michael" def set_age(self, age): self.age = age from types import MethodType s.set_age = MethodType(set_age, s) # Bind a method to an instance s.set_age(25) def set_score(self, score): self.score = score >>> Student.set_score = set_score # Bind a method to class >>> s.set_score(100) >>> s.score >>> class Student(object): >>> __slots__ = ("name", "age") # Use tuple to define the property names allowed to be bound >>> s = Student() >>> s.name = "Michael" # Can bind >>> s.score = 99 # AttributeError will be reported because of what happens first Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Student' object has no attribute 'score'