Python study notes (5)-class and instance

1. Creation and simple use

Class can reflect reality

Code:

class Dog():  # 类名首字母大写
    """模拟小狗的简单测试"""

    def __init__(self, name, age):  # 该方法在类创建的时候会自动运行,类似java的构造函数,注意方法名开头和末尾各有两个下划线
        """初始化属性name和age"""
        self.name = name
        self.age = age

    def sit(self):  # 每个与类相关联的方法,都会传入参数self
        """模拟坐的动作"""
        print(self.name.title() + " 坐下")  # 可获取初始化方法中的值,因传递了参数self

    def roll(self, count):  # 可根据需求自定义要传入的参数,但是self是固定的
        """模拟打滚的动作"""
        print(self.name.title() + " 滚了 " + str(count) + " 圈")


my_dog = Dog('二哈', 3)  # 此处要传入类的初始化方法里的参数
print("我的小狗名字是:" + my_dog.name + "\n年龄是:" + str(my_dog.age))
my_dog.sit()
my_dog.roll(4)  #传入自定义的count参数

result:

我的小狗名字是:二哈
年龄是:3
二哈 坐下
二哈 滚了 4 圈

2. Use classes and instances

First create a Car class

class Car():
    """模拟汽车"""

    def __init__(self, make, model, year=2016):  # 默认时间为2016,如果指定参数了,则按照传入的参数处理,同上一章内容
        """初始化汽车数据"""
        self.make = make
        self.model = model
        self.year = year

    def describe(self):
        """返回描述信息"""
        message = "车类别:" + self.make + " 车型号:" + self.model + " 制造时间:" + str(self.year)
        return message  # 也可以直接打印


my_car_1 = Car('奥迪', 'R8', 2015) # 指定时间参数是2015
my_car_2 = Car('宝马', 'Z7') # 再创建一个实例,没有指定时间参数
print(my_car_1.describe())
print(my_car_2.describe())

result:

车类别:奥迪 车型号:R8 制造时间:2015
车类别:宝马 车型号:Z7 制造时间:2016

Modify the attribute value of the created instance

( Note: After modification, only the attribute value of the instance is changed, and the attribute values ​​of other instances created by the same class are not affected )

Code:

class Car():

    # --snip--

# 修改属性的值,直接访问修改,也可将该逻辑写在类创建的一个函数中,直接调用修改
my_car_1.year = 2000  # 制造时间改为2000年
print(my_car_1.describe())
my_car_1.color = 'red' # 增加属性的值,直接赋值给新属性即可,同字典
print(my_car_1.color)
print(my_car_2.color)  # 此句报错,因为car2并没有color属性

result:

车类别:奥迪 车型号:R8 制造时间:2000  
red
AttributeError: Car instance has no attribute 'color'

3. Class access restrictions

There are access control symbols in java, public,privateand there are control symbols in attributes in python, in the following classes.

Code:

class Person():
    def __init__(self, name, age):
        self.__name = name  # 由两个下划线开始的属性表示类的私有属性,外部无法正常访问
        self.__age = age

    def say(self):  # 私有属性只能自己内部访问
        print ('name:' + self.__name + 'age:' + str(self.__age))


p1 = Person('吴彦祖 ', 18)
p1.say()
print (p1.__name) # 此句报错,同理,无法修改相应属性

result:

name:吴彦祖 age:18
AttributeError: Person instance has no attribute '__name'

Same as java, if you want to access or modify externally, you can create set()and get()method inside the class , as follows

Code: ( new set and get methods added to the class )

class Person():

    # --snip--

    def set_name(self, name):  # 可在方法中控制,避免修改成无效的数据
        self.__name = name

    def get_name(self):
        return self.__name

p1 = Person('吴彦祖', 18)  #  获取实例
print (p1.get_name())  # 访问属性
p1.set_name('刘德华') # 修改属性
print (p1.get_name()) # 访问属性

result:

吴彦祖
刘德华

Tip: Sometimes you will encounter variables that start with a single underscore, for example _name, it means that they are recommended as private variables, but they can still be accessed externally (I don’t know how to design it for Mao, so remember it for now, and modify it when you know it)

Private variables starting with a double underscore are actually accessible from outside, for example

p1._Person__name

It is because the __name attribute is encapsulated inside the python class, but it is not recommended to write this, because different versions of Python interpreters may change __name to different variable names

The last thing to note is: when adding and modifying attributes, you cannot add or modify private attributes. E.g

p1 = Person('吴彦祖', 18)
p1.__name = '刘德华'  # 本意修改name的值
print (p1.get_name()) # 实际上并未修改
print (p1.__name) # 只是新增添了__name属性

result:

吴彦祖
刘德华

But it can be p1._Person__namemodified by method, but it is not recommended for the same reason as above

4. Inheritance

1. When the subclass is created, the method of the parent class needs to be called in the initialization method to __init__()obtain all the properties and methods of the parent class. You can also define your own unique properties and methods, and override the
code of the parent class  :

class ElectricCar(Car):  # 继承父类时,将父类写入括号内即可
    """电动车"""

    def __init__(self, make, model, year):
        """初始化父类的属性"""
        super().__init__(make, model, year)  # 注意super的括号,→_→
        # 初始化自己独有的属性
        self.battery = 70

    # 定义独有的方法
    def describe_battery(self):
        print("电池容量:" + str(self.battery))


my_tesla = ElectricCar('特斯拉', 'S', 2011)
print(my_tesla.describe())
my_tesla.describe_battery()

result:

车类别:特斯拉 车型号:S 制造时间:2011
电池容量:70

2. Override the method of the parent class, similar to java, the instance only executes the method of the same name of the subclass

If there are fill_gasmethods in the Car class , but they are meaningless for the subclass of electric cars, the subclass ElectricCar can override the fill_gasmethods of the parent class and give friendly tips. 
Code:

class ElectricCar(Car):  # 继承父类时,将父类当做参数

    # --snip--

    # 重写父类的方法,方法名相同
    def fill_gase_tank(self):
        """电动车没有汽油"""
        print("电动车不需要加油,你四不四洒.")

# --snip--
my_tesla.fill_gase_tank()

result:

电动车不需要加油,你四不四洒.

3. You can use the instance as an attribute of a class

For example, create a new Battery class

class Battery():
    """电池类"""

    def __init__(self, battery_size=10):  #默认10
        self.battery_size = battery_size

    def describle(self):
        print("电池容量是:" + self.battery_size)

Pass the Battery class as a parameter to the ElectricCar class and modify the initialization method
code of the ElectricCar class  :

def __init__(self, make, model, year):
    """初始化父类的属性"""
    super().__init__(make, model, year)  
    # 初始化自己独有的属性
    self.battery = Battery()  # 此处直接新建Battery的实例赋值给battery属性,没有参数传递,使用默认值10


Code when calling  :

my_tesla.battery.describle()

result:

电池容量是:10

4. Polymorphism and python's duck type

Polymorphism in java, the parent class defines a method A, and the subclass has a method A with the same name. If the parameter passed in to call other methods B of the parent class (call A) is the type of the parent class, the corresponding subclass is called Duplicate name method. E.g

Code:

class A():
    def say(self): # A中有方法say()
        print ('A说话了')

    def say_twice(self, A): # 调用say方法,但是传入A类型的数据
        A.say()
        A.say()


class B(A):  # B中有方法say()
    def say(self):
        print ("B说话了")


class C(A):  # C中有方法say()
    def say(self):
        print ("C说话了")

a = A()
b = B()
c = C()

a.say_twice(b) # 调用A的say_twice方法,传入子类b的实例,因为b继承自A,所以调用b的say方法
a.say_twice(c) # 同上

result:

B说话了
B说话了
C说话了
C说话了

Because java is a static language, the data type passed in the method of the defined class, that is, the data type required by the symbol can be passed in, while python is a dynamic language, as long as the class has a method with the same name (say() in the code above) , You can pass in an instance of this class, for example, define a D class, including the say method

Code:

class D():
    def say(self):
        print ('D没继承,照样说话了')

d = D()
a.say_twice(d)  #  传入D的实例d,虽然没有继承A,但是有say方法,同样可以执行D的say方法,若不包含say方法,则这样调用报错

result:

D没继承,照样说话了
D没继承,照样说话了

Such a type is a duck type (looks like a duck, it is a duck → _ → don’t know how to use a duck for hair)

5. Import the class

Similar to the previous import function, use the from xxx impoort xxxstatement

from car import Car  # 第一个car是car.py文件,第二个Car是类,即从某个.py文件中导入某个类
from car import Car, ElectricCar #导入多个类,用逗号分开
import car # 或者直接导入整个模块,同上一章,使用的时候用 car.xxx
from car import * #导入某个模块的所有类和方法,不建议这样用,可能会和当前文件的某些类或者函数名重合导致出错

6, Python standard library

The Python standard library is a set of modules that come with the system, containing many commonly used method 
codes:

from collections import OrderedDict # 导入有序字典

users_age = OrderedDict()  # 返回一个有序的字典

users_age['大娃'] = 1 
users_age['二娃'] = 2
users_age['三娃'] = 3


for name, age in users_age.items():
    print("名字是:" + name + " 年龄是:" + str(age))

Result:  output in the order of addition

名字是:大娃 年龄是:1
名字是:二娃 年龄是:2
名字是:三娃 年龄是:3

 

Guess you like

Origin blog.csdn.net/weixin_38452841/article/details/108368378