Guo Wei Practical Python Programming MOOC: Chapter 13 Object-Oriented Programming

<Learning records, for your own reference>

1. The concept of class and object

1. Class and object: an instance of a class is called an "object", a class represents a common feature of a thing, and an object is a specific individual thing

2. The method of generating the object: class name (parameter 1, parameter 2)

3. Class writing:

class 类名:
    def _init_(self, 参数1, 参数2, ...):  # 构造函数,每个类必须有
        ...
    def 成员函数1(self, 参数1, 参数2, ...):
        ...
    def 成员函数2(self, 参数1, 参数2, ...):
        ...

# 矩阵类示例:
class rectangle:
    def _init_(self, w, h):
        self.w, self.h = w, h
    def area(self):
        return aslf.w * self.h
    def perimeter(self):
        return 2 * (self.w + self.h) 

def main():
    w, h = map(int, input().split())  # 输入2,3
    rect = reactangle(w,h)  # 生成一个reactangle对象
    print(rect.area(), rect.perimeter())  # 6,10
    rect.w, rect.h = 10, 20
    print(rect.area(), rect.perimeter())
    rect2 = rectangle(2, 3)
    print(rect.area(), rect.perimeter())

main()

self does not correspond to the actual parameter, so you don’t need to write it when writing

4. The role of the class: to bundle the data and the function of manipulating the data together, so that it can be used as a whole

5. Classes in Python:

       The type name is the class name, such as: float, str, list, dict...

        Constants of combined data types such as decimals, complex numbers, strings, tuples, lists, sets, and dictionaries are all objects, and functions are also objects, but integer constants are not objects

        Various libraries are composed of classes, such as: turtle, jieba...

        You can also customize the class

Second, the comparison of objects

  • All classes in Python, including custom classes, have the __eq__ method
  • The value of x == y is the value of x.__eq__(y) (x is treated as an object, __eq__() is a member function of the class to which the object belongs, and x is an integer constant, which is wrong); if x.__eq__ (y) is not defined, then it is the value of y.__eq__(x). If both x.__eq__(y) and y.__eq__(x) are not defined, then x == y is also not defined (not applicable when both x and y are integer constants)
print(24.5.__eq__(24.5))  #True
  •  a != b is equivalent to a.__ne__(b), or b.__ne__(a) if a.__ne__(b) is not defined)
  • By default a.__ne__(b) is equivalent to not a.__eq__(b)
  • a < b is equivalent to a.__lt__(b) a > b is equivalent to a.__gt__(b)
  • a <= b is equivalent to a.__le__(b) a >= b is equivalent to a.__ge__(b)

Comparison of custom objects

  • By default, the __eq__ method of a custom class is used to determine whether the ids of two objects are the same (a==b and a is b have the same meaning, both are "whether a and b point to the same place")
  • By default, objects of custom classes cannot be compared in size, because their __lt__, __gt__, __le__, __ge__ methods are all set to None
# 对象比较大小程序实例
class point:
    def __init__(self, x, y=0):
        self.x, self.y = x, y
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y
    def __lt__(self, other):  # 使两个point对象可以用<进行比较
        if self.x == other.x:
            return self.y < other.y
        else:
            return self.x < other.x
a, b = point(1,2), point(1,2)
# a和b分别是两个对象,本来调用默认的__eq__会不等,因为不指向同一个位置
# 但是改写后的__eq__判断内容是否相等
print(a == b)  # True
print(a != b)  # False
print(a < point(0, 1))  # 等价于 a.__lt__(point(0,1))
print(a < point(1, 3))  # True
lst = [a, point(-2, 3), point(7, 8), point(5, 9), point(5, 0)]
lst.sort()
for p in lst:
    print(p.x, p.y, end=",")
# 自定义重写__str__方法,可以将对象转字符串
class point:
    def __init__(self, x, y):
        self.x, self.y = x, y
    def __str__(self):
        return ("(%d,%d)" % (self.x, self.y))
print(point(3, 5))
print(str(point(2, 4)))

3. Inheritance and derivation

For example, to write primary school students, middle school students, college students...

All students have common characteristics, and each student has its own characteristics. Optionally use inheritance (derivation)

 The benefit of class B "inheriting" class A: class B automatically has all the properties and methods of class A

class 类名(基类名):
    ...

object class

All classes are derived classes of the object class, and thus have various properties and methods of the object class

Some classes __lt__, __gt__ and other methods are set to None, so the objects cannot be compared in size

4. Static properties and static methods

  • Static properties are shared by all objects, there is only one copy
  • Static methods do not act on a specific object and cannot access non-static properties
  • The purpose of static properties and static methods is to write less global variables and global functions
class employee:
    totalSalary = 0 #静态属性,记录发给员工的工资总数
    def __init__(self,name,income):
        self.name, self.income = name, income
    def pay(self,salary):
        self.income += salary
        employee.totalSalary += salary
    @staticmethod
    def printTotalSalary():  # 静态方法
        print(employee.totalSalary)

e1 = employee("Jack", 0)
e2 = employee("Tom", 0)
e1.pay(100)
e2.pay(200)
employee.printTotalSalary() #>>300 用类名调用静态方法
# 静态方法不能作用在具体的对象上,这个虽然写了e1..printTotalSalary()打印出结果了,
# 但是printTotalSalary()和e1其实没有关系,只跟e1e2所属类有关,所以这个写法和上面的其实一样
e1.printTotalSalary() #>>300
e2.printTotalSalary() #>>300
print(employee.totalSalary) #>>300

Static properties and static methods are used to replace global variables and global functions, so that global variables and global functions are bound to the class, making the relationship between it and the class clear at a glance.

Five, the object as a collection element or dictionary key

"hashable":

  • Only things that can be hashed can be used as keys of dictionaries and elements of collections
  • hash(x) is defined, and a value can be calculated, that is, x can be hashed
  • hash(x) = x (if x is an integer constant) hash(x) = x.__hash__() (if x is not an integer constant, x is an object)
  • The object class has a __hash__() method that returns an integer

The __hash__ member functions of lists, sets, and dictionaries are all set to None, so they cannot be elements of sets, or keys of dictionaries, because hash values ​​cannot be calculated.

 The hash values ​​of integer type variables, decimals, strings, and tuples are calculated based on their values. As long as the values ​​are the same, the hash values ​​are the same.

x = 23.1
print(x.__hash__(), 23.1.__hash__())  #230584300921372695 230584300921372695
x = 23
print(x.__hash__(), hash(23))  # 23 23
x = (1, 2)
print(x.__hash__(), (1, 2).__hash__(), hash(x))  # 3713081631934410656 3713081631934410656 3713081631934410656
x = "ok"
print(x.__hash__(), "ok".__hash__())  # -423760875654480603 -423760875654480603

Hash value and the relationship between dictionaries and sets

 If dt is a dictionary, the calculation process of dt[x] is as follows:

  1. Find the number of the slot where x should be based on hash(x)
  2. If the slot has no elements, it is considered that there is no element with key x in dt
  3. If there is an element in the slot, the view finds an element y in the slot, so that the key of y is equal to x. If found, dt[x] is the value of y, if not found, dt[x] is not defined, that is, there is no element whose key is x in dt.

class A:
    def __init__(self, x):
        self.x = x
a, b = A(5), A(5)  # a,b的值相同,但两个A(5)不是同一个,因此a和b的id不同
dt = {a:20, A(5):30, b:40}  # 三个元素的键id不同,因此在不同的槽里
print(len(dt), dt[a], dt[b]) #>>3 20 40 dt[b]求键为b的元素的值
print(dt[A(5)])  # 找一个键为A(5)的元素的值,找不到,因为A(5)是一个新的对象,不是dt里面一个元素的键

Whether objects of custom classes are hashable

# 自定义类只重写__hash__,不重写__eq__

class A:
    def __init__(self, x):
        self.x = x
    def __hash__(self):  # 重写__hash__
        return hash(self.x)
c = A(1)
dt = {A(1):2, A(1):3, c:4}
# 三个元素的键哈希值相同,但id不同,它们在同一个槽里
print(len(dt))  # 3
for a in dt.items():
    print(a[0].x, a[1], end=",")  # 1 2,1 3,1 4,
print(dt[c])  # 4
print(dt[A(1)])  # runtime error
# 因不存在元素的键x,满足 x == A(1) (特指最后一行的A(1)) 
# 默认的==号会调用默认的__eq__,默认的__eq__判断相等是看id是否相同,是否指向同一个地方



# 自定义类同时重写__hash__和__eq__

class A:
    def __init__(self,x):
        self.x = x
    def __eq__(self,other):
        if isinstance(other,A): #判断other是不是类A的对象
            return self.x == other.x
        elif isinstance(other,int): #如果other是整数
            return self.x == other
        else:
            return False
    def __hash__(self):
        return self.x

a = A(3)
print(3 == a)  # True 等价于a.__eq__(3)调用重写的函数
b = A(3)
d = {A(5):10, a:32, A(3):30}
print(len(d),d[a],d[b],d[3])  # 2(因为a和A(3)被认为是重复的了) 30 30 30

Guess you like

Origin blog.csdn.net/m0_46303430/article/details/125884450