大家好,又见面了,我是你们的朋友全栈君。
本文主要针对python的package、面向对象编程等进行详述。
在Python中,一个.py文件就称之为一个模块(Module),不同的文件目录称为包(Package),每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。
与java相同,python也有public/private等属性和方法,在一个模块中(Module),是通过”_”前缀来实现的,正常的函数和变量名是公开的(public),可以被直接引用,比如:abc,x123,PI等;类似“__xxx__”这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如上面的“__author__”,“__name__”就是特殊变量,hello模块定义的文档注释也可以用特殊变量“__doc__”访问,我们自己的变量一般不要用这种变量名;类似_xxx和__xxx这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc,__abc等;
Python module的规范格式
#!/usr/bin/env python3
# 第一行注释可以让这个hello.py文件直接在Unix/Linux/Mac上运行
# -*- coding: utf-8 -*-
# 第2行注释表示.py文件本身使用标准UTF-8编码
' a test module '
# 一个字符串,表示模块的文档注释,任何模块代码的第一个字符串都被视为模块的文档注释;
__author__ = 'Michael Liao' # 变量把作者写进去,这样当你公开源代码后别人就可以瞻仰你的大名
import sys
def test():
args = sys.argv #类似于java main函数中的main(String[] args)中的args
if len(args)==1:
print('Hello, world!')
elif len(args)==2:
print('Hello, %s!' % args[1])
else:
print('Too many arguments!')
if __name__=='__main__':
test()
# 当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__,而如果在其他地方导入该hello模块时,if判断将失败,因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。
类是创建实例的模板,而实例则是一个一个具体的对象,各个实例拥有的数据都互相独立,互不影响,体现了封装特性。
class Student(object):
def __init__(self, name, score): # 注意到__init__方法的第一个参数永远是self,表示创建的实例本身
self.name = name
self.score = score
def print_score(self):
print('%s: %s' % (self.name, self.score))
bart = Student('Bart Simpson', 59)
lisa = Student('Lisa Simpson', 87)
bart.print_score()
lisa.print_score()
输出结果:
Bart Simpson: 59
Lisa Simpson: 87
class Animal(object):
def run(self):
print('Animal is running...')
class Dog(Animal):
def run(self):
print('Dog is running...')
def eat(self):
print('Eating meat...')
class Cat(Animal):
def run(self):
print('Cat is running...')
print("继承")
dog = Dog()
dog.run()
cat = Cat()
cat.run()
print("多态")
def run_animal(animal):
animal.run()
run_animal(Animal())
run_animal(Dog())
run_animal(Cat())
输出结果:
继承Dog is running...Cat is running...多态Animal is running...Dog is running...Cat is running...
对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了。
class Timer(object): def run(self): print('time run...')run_animal(Timer())
输出结果:
time run...
1.type(),判断对象类型,type(“abc”),type(123)
2.isinstance() 判断继承对象的类型
a = Animal()
isinstance(a, Animal)
3.dir() 获得一个对象的所有属性和方法
print("#获取对象的方法")
print(dir(dog))
输出结果:
#获取对象的方法['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'eat', 'run']
class Student(object):
name = 'Student'
from types import MethodType
class Student(object):
pass
s = Student()
s.name = 'Michael' # 动态给实例绑定一个属性
print(s.name)
def set_age(self, age): # 定义一个函数作为实例方法
self.age = age
s.set_age = MethodType(set_age, s) # 给实例绑定一个方法
s.set_age(25) # 调用实例方法
print(s.age) # 测试结果
# 给一个实例绑定的方法,对另一个实例是不起作用的
# 为了给所有实例都绑定方法,可以给class绑定方法
def set_score(self, score):
self.score = score
Student.set_score = set_score
s.set_score(100)
print(s.score)
class Student(object):
__slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
s = Student() # 创建新的实例
s.name = 'Michael' # 绑定属性'name'
s.age = 25 # 绑定属性'age'
s.score = 99 # 绑定属性'score'
输出结果:
Traceback (most recent call last): line 7, in <module> s.score = 99 # 绑定属性'score'AttributeError: 'Student' object has no attribute 'score'
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/149562.html原文链接:https://javaforall.cn