Python学习 DAY 8

DAY 8

Python中,方法没有重载

Python 中,方法的的参数没有声明类型(调用时确定参数的类型),参数的数量也可以由 可变参数控制。因此,Python 中是没有方法的重载的。定义一个方法即可有多种调用方式, 相当于实现了其他语言中的方法的重载。

如果我们在类体中定义了多个重名的方法,只有最后一个方法有效。

方法的动态性

Python 是动态语言,我们可以动态的为类添加新的方法,或者动态的修改类的已有的方法。

#测试方法的动态性

class Person:

    def work(self):
        print("努力上班!")

def playgame(a):
    print("{0}在玩游戏".format(a))
def work2(a):
    print("好好工作,努力上班!")

Person.Play = playgame #可以定义新的方法
p = Person()
p.work()  #结果:努力上班!
p.Play()  #等价于Person.Play(p)
          #结果:<__main__.Person object at 0x0000024BEBC20FD0>在玩游戏

Person.work = work2 #还可以修改老的方法
p.work()  #结果:好好工作,努力上班!

私有私有属性和私有方法(实现封装)

Python 对于类的成员没有严格的访问控制限制,这与其他面向对象语言有区别。关于私有 属性和私有方法,有如下要点:

  1. 通常我们约定,两个下划线开头的属性是私有的(private)。其他为公共的(public)。
  2. 类内部可以访问私有属性(方法)
  3. 类外部不能直接访问私有属性(方法)
  4. 类外部可以通过“_类名__私有属性(方法)名”访问私有属性(方法)

方法本质上也是属性

#测试私有属性、私有方法

class Employee:

    __school = "NJUST"  #私有类属性

    def __init__(self,name,age):
        self.name=name
        self.__age=age #age为私有属性

    def __work(self):  #私有方法
        print("好好工作!")
        print("年龄:",self.__age) #类内部可以访问私有属性
        print("学校:",Employee.__school)

e = Employee('Lee',20)
print(e.name)
print(e._Employee__age) #访问私有属性的方法,因为私密属性就是以此名字保存
e._Employee__work()  #调用私有方法
print(Employee._Employee__school)

结果:

Lee
20
好好工作!
年龄: 20
学校: NJUST
NJUST

@property 装饰器

@property 可以将一个方法的调用方式变成“属性调用”。

@property 主要用于帮助我们处理属性的读操作、写操作。

#简单测试@property的用法

class Employee:

    @property
    def salary(self):
        print("salary running")
        return 10000

emp1 = Employee()
print(emp1.salary)  
#结果:salary running 
#     10000
class Employee:
    def __init__(self,name,salary):
        self.__name=name
        self.__salary=salary

    def get_salary(self):
        return self.__salary

    def set_salary(self,salary):
        if 1000<salary<50000:
            self.__salary = salary
        else:
            print("录入错误,薪水应在1000~50000")

emp1 = Employee("Lee",20000)
print(emp1.get_salary()) #结果:20000
emp1.set_salary(30000)
print(emp1.get_salary()) #结果:30000

@property的实现比较复杂,我们先考察如何使用。把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值,于是,我们就拥有一个可控的属性操作:

只定义getter方法,不定义setter方法就是一个只读属性

使用@property装饰器实现上功能:

class Employee:
    def __init__(self,name,salary):
        self.__name=name
        self.__salary=salary

    @property          #相当于 salary 属性的 getter 方法
    def salary(self):
        return self.__salary

    @salary.setter
    def salary(self,salary):
        if 1000<salary<50000:  #相当于 salary 属性的 setter 方法
            self.__salary = salary
        else:
            print("录入错误,薪水应在1000~50000")


emp1 = Employee("Lee",20000)
print(emp1.salary) #结果:20000
emp1.salary = 30000
print(emp1.salary) #结果:30000

属性和方法命名总结

· _xxx:保护成员,不能用“from module import * ”导入,只有类对象和子类对象能访 问这些成员。

· xxx:系统定义的特殊成员

· __xxx: 类中的私有成员,只有类对象自己能访问,子类对象也不能访问。(但,在类外 部可以通过“对象名. _类名__xxx”这种特殊方式访问。Python 不存在严格意义的私有成员)

注:再次强调,方法和属性都遵循上面的规则。

类编码风格

  1. 类名首字母大写,多个单词之间采用驼峰原则。
  2. 实例名、模块名采用小写,多个单词之间采用下划线隔开。
  3. 每个类,应紧跟“文档字符串”,说明这个类的作用。
  4. 可以用空行组织代码,但不能滥用。在类中,使用一个空行隔开方法;模块中,使用两 个空行隔开多个类。

第五章实操作业

1.定义一个函数实现反响输出一个整数。比如:输入 3245,输出 5432.

a = input("请输入一个整数:")
def t1(x):
    z = reversed(list(a))
    n = ''.join(list(z))
    return n
print(t1(a))
  1. 编写一个函数,计算下面的数列:
a = int(input("输入一个数字:"))
def f1(x):
    b = 0
    for i in range(x):
        b += (i+1)/(i+2)
    print(b)

f1(a)
  1. 输入三角形三个顶点的坐标,若有效则计算三角形的面积;如坐标无效,则给出提 示。
import math


def isvalid(a=0.0, b=0.0, c=0.0):
    """判断三条边长是否符合三角形的定义:任意两边之和大于第三边或者任意两边之差小于第三边"""
    side = [a, b, c]
    side.sort() #升序排序
    if side[0] + side[1] > side[2] or side[2] - side[1] < side[0]:
        return True
    else:
        return False


def calculate_area():
    """获取三角形的三个顶点坐标并计算该三角形的面积"""
    x1, y1 = map(int, input('请输入第一个顶点坐标(格式:横坐标 纵坐标):').split())
    x2, y2 = map(int, input('请输入第二个顶点坐标(格式同上):').split())
    x3, y3 = map(int, input('请输入第三个顶点坐标(格式同上):').split())

    # 计算三条边长
    side1 = math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
    side2 = math.sqrt((x1 - x3) ** 2 + (y1 - y3) ** 2)
    side3 = math.sqrt((x2 - x3) ** 2 + (y2 - y3) ** 2)

    # 调用 isvalid() 函数,判断是否能够构成三角形
    if isvalid(side1, side2, side3):
        # 计算半周长
        s = (side1 + side2 + side3) / 2
        # 计算面积
        area = (s * (s - side1) * (s - side2) * (s - side3)) ** 0.5
        print('三角形的面积为:{:.2f}'.format(area))
    else:
        print('坐标无效,无法构成三角形')


if __name__ == '__main__':
    calculate_area()
  1. 输入一个毫秒数,将该数字换算成小时数,分钟数、秒数。
def f1():
    ms = int(input('请输入毫秒数:'))    # 保留两位小数,但若ms太小,h就会显示为0。
    s = round(ms / 1000, 2) #四舍五入,保留两位小数
    m = round(s / 60, 2)
    h = round(m / 60, 2)
    print('{0}换算后等于{1}秒,等于{2}分钟,等于{3}小时'.format(ms, s, m, h))

f1()

5.使用海龟绘图。输入多个点,将这些点都两两相连。

import turtle as t

def connect_dot(*args):
    """将任意两点相连"""
    # 从第1个点开始依次进行两两连线(不重复)
    for i in range(len(args) - 1):
        for j in range(i + 1, len(args)):
            t.penup()
            t.goto(*args[i])
            t.pendown()
            t.goto(*args[j])

    t.done()


if __name__ == '__main__':
    # 输入n个点
    n = int(input("请输入n个点(n>1):"))
    # 将每个点以元组形式组合成一个列表作为参数传入 connect_dot() 函数
    list_ = [tuple(map(int, input(f'请输入第{i + 1}个点坐标:').split())) for i in range(n)]
    connect_dot(*list_)#*param(一个星号),将多个参数收集到一个“元组”对象中
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值