您的位置:首页 > 编程语言 > Python开发

Python 基础——Python中的类

2015-10-30 12:36 597 查看
基本概念体系
两种类的数据属性

特殊的类属性

属性隐藏

三种方法
实例方法

类方法

静态方法

访问控制
单下划线_开头

双下划线开头

—— 每个现象后面都隐藏一个本质,关键在于我们是否去挖掘

基本概念体系

两种类的数据属性

class Student():
```
This is a Student class.
```
count = 0
books = []
def __init__(self, name, age):
self.name = name
self.age = age


在以上的
Student
类中,
count
books
age
name
都被称为类的数据属性,它们又可分为类数据属性(即不依赖实例)和实例数据属性(依赖于某一具体实例)

下面通过一段演示代码,了解两种数据属性的使用方法:

>>>Student.books.extend(['python', 'machine learning'])
>>>Student.books
['python', 'machine learning']

>>>Student.hobbies = ['music', 'film']
>>>Student.hobbies
['music', 'film']

>>>dir(Student)




>>>zhang = Student('zhang', 23)
>>>zhang.name, zhang.age
('zhang', 23)
>>>zhang.gender = 'male'
>>>zhang.gender
'male'

>>>dir(zhang)




>>>zhang.books.append('c++')
>>>zhang.books
['python', 'machine learning', 'c++']

>>>li = Student('li', 23)
>>>li.name, li.age
('li', 23)
>>>li.gender
AttributeError: 'Student' object has no attribute 'gender'

>>>dir(li)




list
类型extend函数与append函数的区别见Python 基础——tuple与list、append与extend

特殊的类属性

这些类属性(以双下划线为开头和结束)是全部的类所共有的:

类属性含义类型
__name__类名字符串
__doc__类的文档字符串
__base__类的所有父类元组
__dict__类的属性组字典
__module__类所属的模块字符串
__class__类对象的类型type

属性隐藏

通过实例修改类属性的时候,一定要慎重,因为可能出现属性隐藏的情况:

>>>zhang.count == Student.count
True
>>>zhang.count += 1
>>>zhang.count == Student.count
False

>>>del zhang.count
>>>zhang.count == Student.count
True

>>>zhang.books = ['Java', 'C#']
>>>zhang.books == Student.books
False
>>>del zhang.books
>>>zhang.books == Student.books
True

>>>whb = Student('whb', 23)
>>>whb.books.append('R')
>>>del whb
AttributeError: books


注:虽然通过实例可以访问类属性,但这种做法并不推荐,从而避免属性隐藏带来的不必要的麻烦。

三种方法

实例方法

以第一个参数为
self
为标识,
self
表示实例,类似于
C++
中的
this
指针。较为简单和常见,此处略去不表

类方法

cls
作为第一个参数,
cls
表示类本身,定义时使用
@classmethod
装饰器,通过
cls
可以访问类的相关属性。

class Student(object):
'''
this is a Student class
'''
count = 0
books = []
def __init__(self, name, age):
self.name = name
self.age = age

@classmethod
def printClassInfo(cls):
print cls.__name__
print dir(cls)
pass

Student.printClassInfo()
wilber = Student("Wilber", 28)
wilber.printClassInfo()


类方法可以通过类名直接访问,也可通过实例访问

静态方法

静态方法没有参数限制,定义的时候使用
@staticmethod
装饰器,同
@classmethod
方法一样,静态方法可以通过类名访问,也可通过实例访问。

class Student(object):
'''
this is a Student class
'''
count = 0
books = []
def __init__(self, name, age):
self.name = name
self.age = age

@staticmethod
def printClassAttr():
print Student.count
print Student.books
pass


访问控制

python不同于C++、Java及其他编程语言,定义了访问控制的关键字,例如public、private、protected等等,而是采用了另外的机制或者说是约定来实现访问权限的控制。

单下划线
_
开头

单下划线
_
开头实现模块(module,可以是一个单独的.py文件)级别的私有化(对模块以外的函数或者类的权限是private),也就是说使用

from SomeModule import *


将不会引入以单下划线
_
开头的变量、函数。

# module1.py
numA = 10
_numA = 20
def foo():
print('numA is %d' % numA)
print('_numA is %d' % _numA)
def _foo():
print('numA is %d' % numA)
print('numA is %d' % _numA)


# module2.py
from module1 import *
print(numA)
foo()
print(_numA)        # NameError: _numA undefined
_foo()              # NameError: _foo undefined


双下划线开头

对于python中的类属性,可通过双下划线
__
实现一定程度的私有化,双下划线开头的属性在运行时会被mangling(混淆)。

class Student(object):
def __init__(self, name, age):
self.name = name
self.age = age
self.__address = "Shanghai"
>>>zhang = Student('zhang', 23)
>>>zhang.__address
AttributeError: 'Student' object has no attribute '__address'
>>>dir(zhang)
['_Student__address'
....
]

>>>zhang._Student__address
'Shanghai'


因为混淆机制(将所在的函数名加入到自己的属性名或者方法名中去)双下划线的另一个重要用途是避免,子类对父类同名属性或方法的命名冲突:

class A(object):
def __init__(self):
A.__private()
A.public()
def __private(self):
print('A.__private()')
def public(self):
print('A.public()')
class B(A):
def __private(self):
print('B.__private()')
def public(self):
print('B.public()')
>>>b = B()
A.__private()
B.public()


实例化B时,由于未定义构造函数__init__,将调用父类的__init__,由于
__
客观上造成的混淆效果,A.__init__(self)中的self.__private()将会变成self._A__private
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python class