python学习之路(14)Python-初识面向对象(核心知识)(2)

类的方法

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

class Person:#这是一个Person类
    def work(self): # 这是一个Person类的一个方法
        print("努力上班!")
p = Person() #正常情况下新建一个p类
p.work() #调用这个类的方法

执行结果:

努力上班!

Python 是动态语言,我们可以动态的新增新的方法或者替换方法。

class Person:#这还是一个Person类
    def work(self): # 这还是一个Person类的一个方法
        print("努力上班!")
#区别从这里开始
def play_game(self):
    print("{0}玩游戏".format(self))
def work2(s):
    print("好好工作,努力上班!")

#可以让Person 动态的新增 play_game 方法
Person.play = play_game#把play_game新增到Person里的play方法

Person.work = work2 # 用 work2 替换了 work 方法
p = Person() #还是新建一个p类
p.play()#调用新增的play()的方法
p.work()# 此时调用work()的方法为替换过后的work2方法

新增新的方法或者替换方法就叫做方法的动态性。

1 私有属性(实现封装)

共有属性的例子:

class Employee:
    def __init__(self,name,age):
        self.name = name
        self.age = age

e = Employee("高淇",18)
print(e.name)
print(e.age)
print(dir(e))

执行结果

高淇
18
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name']

私有属性的实现:

class Employee:
    def __init__(self,name,age):
        self.__name = name #定义私有属性,“__”
        self.__age = age

e = Employee("高淇",18)
#print(e.name) #此时再这样调用会出错
#print(e.age) #此时再这样调用会出错

print(e._Employee__name)
print(e._Employee__age)
print(dir(e))

执行结果:多了_类名__

高淇
18
['_Employee__age', '_Employee__name', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

2 私有方法

例子:

class Employee:
    def __init__(self,name,age):
        self.__name = name #定义私有属性,“__”
        self.__age = age

    def __work(self):  # 私有实例方法 通过 dir 可以查到_Employee__work
        print("工作!好好工作,好好赚钱,娶个媳妇!")

p1 = Employee("高淇",27)
print(p1._Employee__name)
print(p1._Employee__age) #通过这种方式可以直接访问到私有属性 。通过 dir 可以查到属性:_Employee__age
#print(p1.__age) #直接访问私有属性,报错
#p1.__sleep() #直接访问私有方法,报错
p1._Employee__work()
print(dir(p1)) #查询类的所有属性、方法

执行结果:

高淇
27
工作!好好工作,好好赚钱,娶个媳妇!
['_Employee__age', '_Employee__name', '_Employee__work', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

从打印的 Employee 对象所有属性我们可以看出。私有属性“__age”在实际存储时是按照“_Employee__age”这个属性来存储的。这也就是为什么我们不能直接使用“__age”而可以使用“_Employee__age”的根本原因。

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

  1. 通常我们约定,两个下划线开头的属性是私有的(private)。其他为公共的(public)。
  2. 类内部可以访问私有属性(方法)
  3. 类外部不能直接访问私有属性(方法)
  4. 类外部可以通过“_类名__私有属性(方法)名”访问私有属性(方法)
    【注】方法本质上也是属性!只不过是可以通过()执行而已。所以,此处讲的私有属性和公有属性,也同时讲解了私有方法和公有方法的用法。如下测试中,同时也包含了私有方法和公有方法的例子。

3 @property 装饰器

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

class Employee:
    @property
    def salary(self):#这本来是一个方法
        return 30000;
emp1 = Employee()
print(emp1.salary) #打印 30000
print(type(emp1.salary)) #打印<class 'int'>
#emp1.salary() #报错:TypeError: 'int' object is not callable
#emp1.salary =1000 #@property 修饰的属性,如果没有加 setter 方法,
# 则为只读属性。此处修改报错:AttributeError: can't setattribute

@property 主要用于帮助我们处理属性的读操作、写操作。对于某一个属性,我们可以直接通过: emp1.salary = 30000

如上的操作读操作、写操作。但是,这种做法不安全。比如,我需要限制薪水必须为 1-10000的数字。这时候,我们就需要通过 getter、setter 方法来处理。
例子:

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

    @property  # 相当于 salary 属性的 getter 方法
    def salary(self):
        print("月薪为{0},年薪为{1}".format(self.__salary,(12*self.__salary)))
        return self.__salary;

    @salary.setter
    def salary(self, salary):  # 相当于 salary 属性的 setter 方法
        if (0 <salary <1000000):
            self.__salary = salary
        else:
            print("薪水录入错误!只能在 0-1000000 之间")

emp1 = Employee("高淇",100)
print(emp1.salary)
emp1.salary = -200 #换成0-100000之间

执行结果:

月薪为100,年薪为1200
100
薪水录入错误!只能在 0-1000000 之间

属性和方法命名总结

· _xxx:保护成员,不能用“from module import * ”导入,只有类对象和子类对象能访问这些成员。
· xxx:系统定义的特殊成员
· __xxx: 类中的私有成员,只有类对象自己能访问,子类对象也不能访问。(但,在类外部可以通过“对象名. _类名__xxx”这种特殊方式访问。Python 不存在严格意义的私有成员)
注:再次强调,方法和属性都遵循上面的规则。

类编码风格

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值