机器学习-python语言基础第八天

补充:包导入的一个小问题,在包的__init__文件中,from…import…,在运行程序中导入包,调用包内模块时,依然要添加前缀包.模块.变量,主要原因是命名空间,在运行文件中,包名指向了包的init文件,而init文件中的导入模块,是模块名指向目标模块,因此才通过包名.模块调用,第一个包名是告诉程序进入包的init文件,第二个模块名是告诉程序在包的init文件进入模块命名空间。另外在包的init文件使用from…import…时,因为时运行当前文件,因此from要符合当前文件的sys.path。
1、面向对象-封装
先看下面的代码

import datetime
class Book:
    count = 0  # 既可以通过类调用,也可以通过实例调用,但实例不能修改,如果自己修改,自己就会创建一个内置属性跟这个重名

    # 初始化函数
    def __init__(self, title, price=0.0, author=' ', pubdata=datetime.date.today(), publisher=None):  # 预定义的,构造函数,有什么属性
        self.title = title  # self传进去的不懂实例
        self.price = price					#价格
        self.author = author					#作者
        self.pubdata = pubdata				#出版时间
        self.__publisher = publisher			#私有变量出版社
        Book.count += 1					

    def print_info(self):
        print('当前这本书的信息如下')
        print('标题{}'.format(self.title))
        print('定价{}'.format(self.price))
        print('作者{}'.format(self.author))
        print('出版社{}'.format(self.publisher))
        print('出版日期{}'.format(self.pubdata))

    # 在控制台输入对象名时的返回值
    def __repr__(self):
        return '图书{}'.format(self.title)

    # print时候用的,如果没有定义这个,print打印时会调用__repr__
    def __str__(self):
        return '[图书:{}]'.format(self.title)

    # 析构函数
    def __del__(self):
        Book.count -= 1

    # 类函数,与实例没关系,python3里可以不写参数,但pycharm会提示,但可以正常运行
    def cls_method(cls):
        print('类函数')

    def static_method():
        print('静态函数,与参数无关')
    #既可以通过类调用,也可以通过对象调用
    @staticmethod
    def static_method1():
        print('静态函数,与参数无关')

在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑。

 book1 = Book('C#', 29.00, 'Tom', datetime.date(2016, 3, 1), 'youpinketang')
 print(book1.title)
 book1.print_info()

如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问。上面程序的__publisher就是私有变量,也可以通过_Book__publisher来访问私有变量,但不建议这么使用。
count属于类变量,既可以通过类调用,也可以通过实例调用,但实例不能修改,如果自己修改,自己就会创建一个内置属性跟这个重名。

print('图书的数量时{}'.format(Book.count))
print('图书的数量时{}'.format(book1.count))

__repr__(self)函数是用在控制台中直接输入类的对象的输出,当程序没有定义__str__(self)时,调用打印时也会调用__repr__。当程序定了__str__时,调用打印时,程序会使用__str__的返回值。

book2 = Book('Flask')
print(book2)

注:datetime.data(年,月,日)会生成一个年月日的对象,调用打印时可以生成年-月-日,datetime.data.today()可以获得当前的年月日,datetime.data.today().year可以返回当年的年份
上述程序中__init__是初始化方法,当定义一个对象时,会自动调用;__del__时析构函数,当一个对象被销毁之前会调用这个函数。

当定义一个方法的参数时cls(python2的用法)或者不给其提供参数时,这个方法是类的方法,可以通过类直接调用,如果定义是有cls,则使用时也要传入一个类的对象。通过对象无法调用。如果一个方法前加了 @staticmethod的装饰器,则这个方法类或者对象都可以调用

Book.cls_method(book2)  # 参数不能省,必须得传一个实例
Book.static_method()
book2.static_method1()
Book.static_method1()

如下代码:

import datetime


class Student:

    def __init__(self, name, birth):
        self.name = name
        self.birth = birth

    def get_age(self):
        return datetime.date.today().year - self.birth.year

    # 属性装饰器
    @property
    def age(self):
        return datetime.date.today().year - self.birth.year

    @age.setter
    def age(self, value):
        raise AttributeError('禁止赋值年龄!')

    @age.deleter
    def age(self):
        raise AttributeError('不能删除')

程序中的@property叫做装饰器,它使得一个方法可以像调用属性一样被调用。

print(s.age)

@age.setter、@age.deleter与装饰向对应使用,分别时给age赋值时调用,删除age时调用

s.age = 20
del (s.age)

2、面向对象-继承
在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。

import datetime
class Department:
    def __init__(self,department,phone,manager):
        self.department = department
        self.phone = phone
        self.manager = manager

    def __repr__(self):
        return '<部门>:{}'.format(self.department)

class Employee:
    def __init__(self, department:Department, name, birth, salary):
        self.department = department
        self.name = name
        self.birth = birth
        self.salary = salary

    def __repr__(self):
        return '员工:{}'.format(self.name)

    @property
    def age(self):
        return datetime.date.today().year - self.birth.year

    def give_raise(self, percent, bonus=0.0):
        self.salary = self.salary * (1 + percent + bonus)

    def working(self):
        print('员工:{}正在工作'.format(self.name))


class Programer(Employee):
    def __init__(self, department, name, birth, salary, speciality, project):
        super().__init__(department, name, birth, salary)
        self.speciality = speciality
        self.project = project

    def working(self):
        print('程序员:{}正在开发项目:{}'.format(self.name, self.project))

class HR(Employee):
    def __init__(self,department, name, birth, salary, level=1):
        Employee.__init__(self,department, name, birth, salary)
        self.level =level

在上述代码中,继承时,在定义的类开始加一个括号,写明继承的父类,python支持多继承,当发生多继承时,super显得不明确,因此可以使用类名.方法的方式进行集成初始化定义。
在类中,某个参数时一个确定类型,可以通过:类型来提示用户,但并不是强制的,用户依然可以改用其他参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值