Python面向对象编程
2021/9/8 12:36:06
本文主要是介绍Python面向对象编程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- 面向对象编程
- 类和实例
- 访问限制
- 继承和多态
- 鸭子类型
- 获取对象信息
- 使用type()判断
- 使用isinstance
- 使用dir()
- getattr()`、`setattr()`以及`hasattr()
- 实例属性和类属性
面向对象编程
类和实例
和Java一样,把类作为编程的基本单位。
以Class为基本单位,里面包括属性和方法。
例如,学生类:
class Student(object): def __init__(self, name, score): self.name = name self.score = score def print_score(self): print('%s: %s' % (self.name, self.score))
括号中的(Object)指的是继承下来的类。
bart = Student('Bart Simpson', 59) lisa = Student('Lisa Simpson', 87) bart.print_score() lisa.print_score()
此处的bart是类的一个实例化,也就是通过类创造了对象。
通过定义一个特殊的__init__
方法,在创建实例的时候,就把name
,score
等属性绑上去:
注:__init__
方法的第一个参数永远是self
,表示创建的实例本身,因此,在__init__
方法内部,就可以把各种属性绑定到self
,因为self
就指向创建的实例本身。(类似于java的this)
无论是什么方法,第一个参数都得是self
访问限制
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__
,在Python中,实例的变量名如果以__
开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问
注:在Python中,变量名类似__xxx__
的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name__
、__score__
这样的变量名。
继承和多态
继承:直接获取父类的属性和变量
多态:子类方法可以覆盖父类同名方法,同时,父类作为参数的函数或者方法都可以不加修改地正常运行,原因就在于多态。
动态语言的鸭子类型特点决定了继承不像静态语言那样是必须的。
鸭子类型
调用对象不看类型,只看方法。
比如:
function calculate(a, b, c) => return (a+b)*c example1 = calculate (1, 2, 3) example2 = calculate ([1, 2, 3], [4, 5, 6], 2) example3 = calculate ('apples ', 'and oranges, ', 3) print to_string example1 print to_string example2 print to_string example3
其中的example3其实是不合理的,因为对于calculate函数所针对的对象应当是一个数。但是,因为str类型支持‘+’,因此这个函数可以执行。
运行结果:
9 [1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6] apples and oranges, apples and oranges, apples and oranges,
那么,不要求str继承int或者float类型,只要支持*和+两个方法就可以了。
再例如:
class Duck: def quack(self): print("这鸭子在呱呱叫") def feathers(self): print("这鸭子拥有白色与灰色羽毛") class Person: def quack(self): print("这人正在模仿鸭子") def feathers(self): print("这人在地上拿起1根羽毛然後给其他人看") def in_the_forest(duck): duck.quack() duck.feathers() def game(): donald = Duck() john = Person() in_the_forest(donald) in_the_forest(john) # 此处的代码在java中无法运行,in_the_forset的参数是duck,但是john是个人。但是在python中这句代码可以运行。python只访问需要的方法,所以只要函数中调用的方法在参数中存在就可以执行 game()
鸭子类型,让python在不继承的情况下,也可以使用多态的特性。
获取对象信息
使用type()判断
用法:
>>> type(123) <class 'int'> >>> type(str) <class 'type'> >>> type('str') <class 'str'>
要判断一个对象是否是函数怎么办?可以使用types
模块中定义的常量:
>>> import types >>> def fn(): ... pass ... >>> type(fn)==types.FunctionType # 函数类型 True >>> type(abs)==types.BuiltinFunctionType True >>> type(lambda x: x)==types.LambdaType # lambdaType类型 True >>> type((x for x in range(10)))==types.GeneratorType # 生成器类型 True
使用isinstance
insinstance()可以用来判断实例和类之间的关系。
用法:isinstance(对象,类),如果对象属于该类就是True,不属于就是False
如果:
object -> Animal -> Dog -> Husky
则
>>> class Animal(object): ... pass ... >>> class Dog(Animal): ... pass ... >>> class Baby(Dog): ... pass ... >>> MT = Baby() >>> isinstance(MT, Dog) True
使用dir()
使用dir()可以获取一个对象所有的属性和方法
>>> dir('abc') ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__ge tnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__' , '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold ', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigi t', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition' , 'removeprefix', 'removesuffix', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
我们自己写的类,也可以加一些常用方法,比如__len__
方法返回长度。在Python中,如果你调用len()
函数试图获取一个对象的长度,实际上,在len()
函数内部,它自动去调用该对象的__len__()
方法,所以,下面的代码是等价的。我们自己写的类,如果也想用len(myObj)
的话,就自己写一个__len__()
方法:
>>> class MyDog(object): ... def __len__(self): ... return 100 ... >>> dog = MyDog() >>> len(dog) 100
getattr()、
setattr()以及
hasattr()
用法:getattr(类对象,属性)
getattr()返回某个属性的值,如果试图获取不存在的属性,会抛出AttributeError的错误。
如果不想抛出错误,可以传入一个default参数,如果属性不存在,就返回默认值。
setattr(对象,属性,值)
添加一个属性并设置他的值
hasattr()
判断某对象是否存在一个属性
例如,对于类Myobject:
>>> class MyObject(object): ... def __init__(self): ... self.x = 9 ... def power(self): ... return self.x * self.x ... >>> obj = MyObject()
>>> hasattr(obj, 'x') # 有属性'x'吗? True >>> obj.x 9 >>> hasattr(obj, 'y') # 有属性'y'吗? False >>> setattr(obj, 'y', 19) # 设置一个属性'y' >>> hasattr(obj, 'y') # 有属性'y'吗? True >>> getattr(obj, 'y') # 获取属性'y' 19 >>> obj.y # 获取属性'y' 19 >>> getattr(obj, 'z', 404) # 获取属性'z',如果不存在,返回默认值404 404
实例属性和类属性
就类似Iava的静态属性。属于类的属性。
给实例绑定属性的方法是通过实例变量,或者通过self
变量:
class Student(object): def __init__(self, name):# 通过self变量 self.name = name s = Student('Bob') s.score = 90 # 通过实例变量
同时,也可以给实例绑定一个方法。
>>> def set_age(self, age): # 定义一个函数作为实例方法 ... self.age = age ... >>> from types import MethodType # 这个类型是Python自带的方法 >>> s.set_age = MethodType(set_age, s) # 给实例绑定一个方法 >>> s.set_age(25) # 调用实例方法 >>> s.age # 测试结果 25
通过Python自带的方法进行绑定。
如果Student
类本身需要绑定一个属性呢?可以直接在class中定义属性,这种属性是类属性,归Student
类所有:
class Student(object): name = 'Student'
这个属性,所有的对象都可以访问。
这篇关于Python面向对象编程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26Python基础编程
- 2024-11-25Python编程基础:变量与类型
- 2024-11-25Python编程基础与实践
- 2024-11-24Python编程基础详解
- 2024-11-21Python编程基础教程
- 2024-11-20Python编程基础与实践
- 2024-11-20Python编程基础与高级应用
- 2024-11-19Python 基础编程教程
- 2024-11-19Python基础入门教程
- 2024-11-17在FastAPI项目中添加一个生产级别的数据库——本地环境搭建指南