Python学习手册之数据封装、类方法、

发布时间:2019-04-10 21:14:17编辑:auto阅读(1934)

    在上一篇文章中,我们介绍了 Python 的内部方法、操作符重载和对象生命周期,现在我们介绍 Python 的数据封装、类方法、静态方法和属性函数。查看上一篇文章请点击:https://www.cnblogs.com/dustman/p/10017357.html

    数据封装
    面向对象编程的一个关键部分是封装,它涉及将相关变量和函数打包到一个简单易用的对象(类的一个实例)中。
    一个相关的概念是隐藏数据,它隐藏了类的实现细节,并提供一个干净的标准接口。
    在其它编程语言中,通常是通过私有方法和属性完成的,这些方法和属性阻止了对类中某些方法和属性的外部访问。
    Python 的设计哲学略有不同。它认为 "我们都是成年人",这意味着你不应该对类的访问设计任意的限制。因此,没有任何方法强制方法或属性是严格私有的。

    但是,还是有一些方法可以阻止人们访问类的内部私有成员。

    弱私有方法和属性在开头只有一个下划线。
    这表明它们是私有的,不应该被外部代码使用。但是,它们基本上只有一个约定,并不阻止外部代码访问它们。
    它唯一的实际效果是,从模块导入 from module_name import * 不会导入以单个下划线开头的变量。

    class Name():
     def __init__(self):
      self.__name = None
    
     def getName(self):
      return self.__name
    
     def setName(self, string):
      #判断value的值是不是整型
      if isinstance(string, str):
       self.__name = string
      else:
       print("Error:不是字符串")
    
    m1 = Name()
    print(m1.getName())
    m1.setName("Lisi")
    print(m1.getName())
    m1.setName(10086)
    m1.__name = "WangWu"
    print(m1.__name)

    运行结果:

    >>>
    None
    Lisi
    Error:不是字符串
    WangWu
    >>>
    上面的例子,属性 __Name 标记为私有,但是还是可以被外部代码访问。

    弱私有方法和属性的名称开头有双下划线,这意味着它们不能从类之外被访问。
    这样做的目的并不是确保它们是私有的,而是如果又具有相同名称的方法和属性的子类,则可以避免出现 bug
    使用这种方法直接访问是无法访问的,但可以通过不同的名称访问。Name 类的私有方法 __privatemethod 可以通过 _Name__privatemethod 方法进行外部访问。

    class Name():
     __name = "ZS"
     def print_name(self):
      print(self.__name)
    
    n = Name()
    n.print_name()
    print(n._Name__name)
    print(n.__Name)

    运行结果:

    >>>
    ZS
    ZS
    AttributeError: 'Name' object has no attribute '__Name'
    >>>
    基本上,Python 通过内部更改名称以包含类名来保护这些成员。

    类方法

    目前为止,我们所看到调用对象的方法都是有类的一个实例调用的,然后传递给方法的 self 参数。
    类方法是不同的 -- 它们由一个类调用,该类被传递给方法的 cls 参数。
    类方法的常见用途是工厂方法,它们使用与传递的类构造函数的参数不同的参数来实例化实例。
    类方法被装饰符 @classmethod 标记为类方法。

    class Book():
     def __init__(self, title):
      self.title = title
    
     @classmethod
     def class_method_create(cls, title):
      book = cls(title=title)
      return book
    
    book1 = Book("use instance_method_create book instance:追风筝的人")
    book2 = Book.class_method_create("use class_method_create book instance:百年孤独")
    print(book1.title)
    print(book2.title)

    运行结果:

    >>>
    use instance_method_create book instance:追风筝的人
    use class_method_create book instance:百年孤独
    >>>

    class_method_create 是类方法,它不在类的实例上调用。而是通过类的方法调用,它返回类 cls 的一个新对象。

    从技术上将,self  cls 参数只是约定;它可以更改为其他任何东西。但是,这种约定被大多数人遵循。

    静态方法
    静态方法与类方法相似,只是没有任何附加参数比如 selfcls。它们与属于类函数的使用方法相同。它们被静态方法装饰器 @staticmethod 定义。

    class Book():
     def __init__(self, title):
      self.title = title
    
     @staticmethod
     def static_method_create(title):
      book = Book(title)
      return book
    
    book1 = Book("use instance_method_create book instance:追风筝的人")
    book3 = Book.static_method_create("use static_method_create book instance:活着")
    print(book1.title)
    print(book3.title)

    运行结果:

    >>>
    use instance_method_create book instance:追风筝的人
    use static_method_create book instance:活着
    >>>

    静态方法的行为类似于普通函数,除了不可以从类的实例中调用它们。

    属性函数
    属性函数提供一种定制化的访问属性的方法
    有些时候我们不想让外界修改属性值,那么通过将属性装饰器 @property 放在方法的上方创建属性函数。这意味着当访问同名的实例属性时,将调用该方法。

    class Animal():
     def __init__(self, name, age):
      self._name = name
      self._age = age
    
     @property
     def name(self):
      return self._name
    
    a = Animal('black dog', 3)
    a.age = 12
    print('Name:', a.name)
    print('Age:', a.age)

    运行结果:

    >>>
    Name: black dog
    Age: 12
    >>>

    下面例子定义了 Animal 类的 isRed 的属性。

    class Animal():
     def __init__(self, color):
      self.color = color
    
     @property
     def isRed(self):
      if self.color == 'red':
       return True
      else:
       return False
    
    a = Animal("red")
    print(a.isRed)

    运行结果:

    >>>
    True
    >>>

    属性函数同样可以使用 setter/getter 设置读写方法。
    setter 函数定义设置属性的值。getter 函数定义获取属性的值。
    要定义获取属性值的函数,使用属性名后面跟着 .setter 关键词,同样 .getter 定义了这个方式属于获取属性值的函数。

    class Animal(object):
     def __init__(self, name, age):
      self._name = name
      self._age = age
      self._color = 'Black'
    
     @property
     def name(self):
      return self._name
    
     @name.setter
     def name(self, value):
      if isinstance(value,str):
       self._name = value
      else:
       self._name = 'No name'
    
     @property
     def age(self):
      return self._age
    
     @age.setter
     def age(self, value):
      if value > 0 and value < 100:
       self._age = value
      else:
       self._age = 0
    
    a = Animal('black dog', 3)
    print('Name:', a.name)
    print('Age:', a.age)
    a.name = 'white dog'
    a.age = 180
    print('Name:', a.name)
    print('Age:', a.age)

    运行结果:

    >>>
    Name: black dog
    Age: 3
    Name: white dog
    Age: 0
    >>>
    

     

     

     

    “为什么在这个世界上,有95%的人会无法成功,而只有那少数的5%会成功,因为大多数人的心里存在着这三个字:不可能。”

关键字