本文旨在帮助从总体上帮助了解Python的一些基本属性,具体的使用技巧需要通过不断实践积累
一、Python的基本特性
二、Python的类
面向对象编程,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
1、类
创建办法:
class Student(object): pass
如果没有合适继承类,使用object类,所有类都会继承的类。通过__init__方法,可以将必须绑定的属性强制写入。
class Student(object): def __init__(self, name, score): self.name = name self.score = score
第一参数永远是self,创建的实例本身。
2、访问限制
在类变量的前加入__,就会变成私有变量。内部能访问,外部不能访问。私有变量的实现其实是对变量别名。
class Student(object):
def __init__(self, name, score):
self.__name = name
self.__score = score
python解释器对外将__name变量改成_Student__name。访问_Student__name还是可以访问__name变量。
类似:__XXX__是特殊变量,可以直接引用,但是有特殊用途,如if __name__ == '__main__':,我们自己变量一般不用这种变量名。这里还是要推荐下小编的Python学习裙:【五 八 八,零 九 零,九 四 二】不管你是小白还是大牛,小编我都欢迎,不定期分享干货,包括小编自己整理的一份2018最新的Python资料和0基础入门教程,欢迎初学和进阶中的小伙伴。在不忙的时间我会给大家解惑
_XXX和__XXX这样的函数和变量“不应该”被直接引用。
3、继承与多态
从现有的class继承,新的class称为子类。被继承的class称为基类、父类、或超类。如:
class Animal(object):
def run(self):
print('Animal is running...')
Dog,Cat从Animal继承:
class Dog(Animal):
pass
class Cat(Animal):
pass
作用:
(1)继承类获得父类的全部功能;Dog,Cat都有run()方法,也可以增加自己的方法。
(2)可以对继承方法修改。当子类和父类都有同一方法时,调用时,子类覆盖父类的方法。提现继承的多态性,一个Dog实例化的对象,即是属于Dog类,也属于Animal类。
(3)继承可以一级一级继承下来。因此一个类可以继承多个类的特性。
4、动态语言和静态语言
编写一个接受Animal类型的变量
def run_twice(animal):
animal.run()
animal.run()
可以对实例后传参,run_twice(Dog())、run_twice(Cat());
对于静态语言,如果需要传入Animal类型,则传入对象必须是Animal类或者它的子类,否则不能调用run方法。但是对于python这种动态语言而言,只需要保证传入对象有一个run()方法就可以了。
class Timer(object):
def run(self):
print('Start...')
因此也能调用run_twice函数调用run()方法。run_twice(Timer())。也就是只要一个对象“看起来像鸭子,走起路来像鸭子”,那它就可以看做鸭子。
5、获取对象信息
(1)type():判断对象类型;
(2)isinstance():判断class的类型,判断一个对象是否属于某个类。能用type判断的类型也能用isinstance()判断。
(3)dir():获取一个对象的所有属性和方法。
(4)之前说的__xxx__有特殊作用,比如__len__方法,我们调用len()函数获取对象长度时,len()函数内部会自动调用__len__()方法。
因此,计算len('ABC')等价'ABC'.__len__()
(5)利用getattr()、setattr、hasattr可以直接操作对象的状态。
hasattr():判断是否有某个属性;
getattr():获取属性值
setattr():设置一个属性值。
三、Python高级属性
1、__slots__
定义一个class,创建实例后,我们可以给实例绑定任何属性和方法。由于动态语言的灵活性。
class Student(object):
pass
实例化,s = Student()
s.name = 'Michiael'
或绑定方法
def set_age(self,age):
self.age = age
from types import MethodType
s.set_age = MethodType(set_age,s)
但是给一个实例绑定的方法,在另一个实例中不起作用。
如果需要限制实例的属性,只允许name和age属性。可以用__slots__变量限制。
class Student(object):
__slots__ = ('name','age')
__slots__定义属性只对当前实例起作用,对于继承的子类不起作用。
2、@property
在绑定属性时,属性的值可以随便改动,无法检查参数。如 s.score = 9999,需要限制score范围,因此可以设置set_score()和get_score()获取成绩
class Student(object):
def get_score(self):
return self._score
def set_score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
s = Student()后,s.set_score(60)是正常的,s.set_score(9999)会报错。
但是这种限制方法,调用比较复杂,是否能实现s.score = 9999这样简单的访问变量,又能检查参数,python的@property能够实现,它是将一个方法变成属性调用。
class Student(object):
@property
def score(self):
return self._score
@score.setter
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
上面将getter方法变成了属性值,@property又创建一个装饰器@score.setter将setter方法变成属性赋值。
3、多重继承
一个子类可以继承多个父类,通过多重继承,一个子类就可以同时获得多个父类的所有功能。
通常类的继承关系。都是主线单一继承下来的。这样在继承多个类时,会导致复杂而庞大的继承链。如果需要混入额外的功能,可以进行同时继承多个类,这种设计成为Mixin。
如:
class Dog(Mammal,RunnableMinxIN, \
CarnivorousMixin):
pass
4、定制类
Pythonc的class中有许多特殊用途的函数,可帮助定制类。
(1)__str__:显示字符
(2)__iter__:需要设置一个类,像for ...in循环访问,类似list或tuple,需要实现__iter__方法。
(3)__getitem__:虽然实现__iter__能够作用for循环,但是还是不能像list那样取元素,如果想像list按照下标取出元素,需要实现__getitem__方法。
def __getitem__(self, n):
a, b = 1, 1
for x in range(n):
a, b = b, a + b
return a
(4)__getattr__:python调用不存在的属性时,一般程序会报错,如果加入__getattr__,Python试图调用,来获取属性。
(5)__call__:调用实例方法时,是通过instance.method()调用,通过__call__可实现在实例本身调用。或者说,将类对象当做函数使用。如:
class DistanceForm(object):
def __init__(self, origin):
self.origin = origin
print "origin :"+str(origin)
def __call__(self, x):
print "x :"+str(x)
p = DistanceForm(100)
p(2000) #类似函数方式,直接赋值调用。
python还有很多定制方法。可查官网。
5、使用元类
type()函数既可以返回一个对象的类型,也可以创建一个新的类型。比如可以用type创建一个类。
Hello = type('Hello', (object,), dict(hello=fn))
创建的参数:
(1)class的名称;
(2)继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法;
(3)class的方法名称与函数绑定,这里我们把函数fn绑定到方法名hello上。除了通过type()动态创建类外,还可以是使用mataclass。元类是类的类。一个实例创建的完整过程应该是,先创建一个元类,元类创建类,类创建实例。
type函数实际就是一个元类,也是Python背后创建所有类的元类。
我们可以自定义元类:
# metaclass是类的模板,所以必须从`type`类型派生:
class ListMetaclass(type):
def __new__(cls, name, bases, attrs):
attrs['add'] = lambda self, value: self.append(value)
return type.__new__(cls, name, bases, attrs)
class MyList(list, metaclass=ListMetaclass): pass
Mylist创建时,是通过ListMetaclass.__new__创建。因此可以修改类的定义,或加入新方法。
__new__()方法接收到的参数依次是:
1、当前准备创建的类的对象;
2、类的名字;
3、类继承的父类集合;
4、类的方法集合。
实例化:
L = MyList() 此时可以实现 add调用。L.add(1)
领取专属 10元无门槛券
私享最新 技术干货