类的使用
Python中一切都是对象,函数是对象,类是对象,变量时对象,字符串是对象,列表和元组也是对象,他的所有一切都是对象。
面向对象编程最基本特征是类和实例。
类是用于定义抽象的对象模型,实例是根据类创建的对象。
class person(object):
address = '中国' # 类属性,没个实例的公共属性
def __init__(self, name, sex, age): # 相当于java中的构造方法
self.name = name # 实例属性
self.sex = sex # 实例属性
self.age = age # 实例属性
def dance(self): # 方法
print(self.name, '跳了一场舞')
hong = person('小红', '女', 18) # 实例化小红,将实例化的对象赋值给变量hong
ming = person('小明', '男', 26)
hua = person('小花', '女', 22)
python类中的访问限制(常用)
1、属性的访问限制,Python 私有属性
Python 类中如果有属性不希望被外部访问,我们可以在属性命名前加下双划线写成( __xx ),那么该属性就不能使用原变量名访问,使得该属性变为本类私有的(伪私有)。
补充说明:加双下划线__xx 的属性,可以通过“ _类名__xx ”可以访问到属性的值。
如下圆类Circle的示例,我们将pi属性开头加上双下划线变成私有属性:
class Circle(object):
__pi = 3.14
def __init__(self, r):
self.r = r
def area(self):
"""
圆的面积
"""
return self.r **2* self.__pi
circle1 = Circle(1)
print(Circle.__pi) # 抛出AttributeError异常
print(circle1.__pi) # 抛出AttributeError异常
通过 Circle.__pi 与 circle1.__pi 访问 __pi 时 都会出现 AttributeError 异常,证明访问权限已被控制。
按照编码规范,他们不应该使用Circle._Circle__pi 访问到__pi属性。(其实还是可以访问 __pi ,可以通过 Circle._Circle__pi 访问到 __pi 属性,他与python的机制有关。)
2、方法的访问限制,Python私有访问
同属性的访问限制,方法的访问限制也是在方法名前加双下划线,写成( __xx ),它也是一种伪私有。
class Circle(object):
__pi = 3.14
def __init__(self, r):
self.r = r
def area(self):
"""
圆的面积
"""
return self.r**2 * self.__pi
def __girth(self):
"""
圆的周长
"""
return 2*self.r * self.__pi
circle1 = Circle(2)
print(circle1.__girth()) # 抛出AttributeError异常
私有化方法后,我们只能在类的内部使用该方法,不能被外部调用。
属性控制,方法需要访问被限制的方法也是 _类名__xx 如 circle1._Circle__girth()。
python中的self和cls的区别
一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法。
而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用。
这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。
- self表示一个具体的实例本身。如果用了staticmethod,那么就可以无视这个self,将这个方法当成一个普通的函数使用。
- cls表示这个类本身。
首先定义一个类A,类A中有三个函数,
foo1为静态函数,用@staticmethod装饰器装饰,这种方法与类有某种关系但不需要使用到实例或者类来参与。
如下两种方法都可以正常输出,也就是说既可以作为类的方法使用,也可以作为类的实例的方法使用。
foo2为正常的函数,是类的实例的函数,只能通过a调用。
foo3为类函数,cls作为第一个参数用来表示类本身. 在类方法中用到,类方法是只与类本身有关而与实例无关的方法。如下两种方法都可以正常输出。
class A(object):
a = 'a'
@staticmethod
def foo1(name):
print 'hello', name
print A.a # 正常
print A.foo2('mamq') # 报错: unbound method foo2() must be called with A instance as first argument (got str instance instead)
def foo2(self, name):
print 'hello', name
@classmethod
def foo3(cls, name):
print 'hello', name
print A.a
print cls().foo2(name)
再看看这两种方法的区别:
既然@staticmethod和@classmethod都可以直接类名.方法名()来调用,那他们有什么区别呢?
从它们的使用上来看,
@staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。
如果在@staticmethod中要调用到这个类的一些属性方法,只能直接类名.属性名或类名.方法名。
而@classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。也就是说在classmethod中可以调用类中定义的其他方法、类的属性,但staticmethod只能通过A.a调用类的属性,但无法通过在该函数内部调用A.foo2()。
Python类中的@classmethod、@staticmethod 装饰方法(需要理解)
@classmethod 用来修饰方法。使用在实例化前与类进行交互,但不和其实例进行交互的函数方法上。不需要表示自身对象的self和自身类的cls参数,就和使用普通的函数一样。
@staticmethod 用来修饰类的静态方法。使用在有些与类相关函数,但不使用该类或该类的实例。如更改环境变量、修改其他类的属性等。不需要self参数,但是第一个参数需要表示自身类的cls参数。
简而言之,在类里有@staticmethod的,可以直接调用,没有加上改装饰器的方法就不能去调用。
@classmethod的话,在类里的所有方法都可以调用的。
两者最明显的区别,classmethod 必须使用类的对象作为第一个参数,而staticmethod则可以不传递任何参数
class A(object):
bar = 1
def foo(self):
print ' call function foo in class A '
@staticmethod
def static_foo():
print 'static_foo'
print A.bar
@classmethod
def class_foo(cls):
print 'class_foo'
print cls.bar
cls().foo()
@property 装饰器
简而言之就是可以在调用的时候不用加()
类里面没有__init__ 的话,@property就失效了
class A(object):
def __init__(self,name,age):
self.name = name
self.age = age
@property
def static_foo(self):
print self.name
return 'yes'
num = A("Liu","21")
num.static_foo