本文共 12093 字,大约阅读时间需要 40 分钟。
1.1 Objects
**Example: [1, 2, 3, 4]
1.2 Object-oriented programming (OOP)
Everything is an object and has a type
Objects are a data abstraction that encapsulate
– Internal representation – Interface for interacting with objectOne can
– Create new instances of objects(explicitly or using literals) – Destroy objects1.3 Advantages of OOP
Bundle data into packages together with procedures that work on them through well-defined interfaces
Divide-and-conquer development
– Implement and test behaior of each class separately – Increased modularity reduces complexityClasses make it easy to reuse code
– Many Python modules define new classes – Each clase has a separate environment (no collision on function names) – Inheritance allows subclasses to redefine or extend a selected subset of a superclass’ behaviorclass Coordinate(object): ...define attributes here ...
Indentation used to indicate which statements are part of the class definition
Classes can inherit attributes from other classes, in this case Coordinate inherits from the object class. Coordinate is said to be a subclass of object, object is a superclass of Coordinate. One can override an inherited attribute with a new definition in the class statement.
当我们定义一个class的时候,我们实际上就定义了一种数据类型。我们定义的数据类型和Python自带的数据类型,比如str、list、dict没什么两样
What are attributes? – data and procedures that “belong” to the class
– data attributes think of data as other objects that make up the class – procedural attributes (methods) think of methods as functions that only work with this class2.1 Creating an instance
class Coordinate(object): # 括号里的内容是class parent,说明此class 会inherit 父class里的所有attribute def __init__(self, x, y): self.x = x # x, y 是instance variables self.y = y '''when calling a method of an object, Python always passes the object as the first argument. By convention, we use self as the name of the first argument of methods.self 相当于是coordinate用于指向自己的一个指针,确保了是在local的environment里运行。也可以用别的名字,但self是一种习惯,每一个class里的procedure都要在第一个attribute的位置写这个。若在class中没有定义__init__函数,那么系统就会去superclass object里寻找。When accessing an attribute of an instance, start by looking within the class definition, then move up to the definition of a superclass, then move to the global environment.'''
# calling the upper classc = Coordinate(3, 4) # don't provide argument for self, python does this automaticallyorigin = Coordinate(0, 0)print c.x, origin.x>>> 3 0>type(c)>>> __main__.Coordinate>type(Coordinate.__init__)>>> function>type(object)>>> type>type(Coordinate)>>> type>print(c)>>><__main__.Coordinate object at 0x000001811CAF8088># 直接print(c)会返回c所在的位置。# 用于判断c是否是type为Coordinate的一个instance>isinstance(c, Coordinate)>>> True'''每call一次coordinate,就会生成一个新的frame,里面存放各自独立的变量。'''
2.2 an environment view of classes
frame --> Coordinate method --> init procedure --> 定义self, x, y当class被call之后,生成的新frame才算是一个instance
上图显示出,通过c.__init__这种方式也可以叫出class里的method,但是根据python不同的版本,可能会产生不同的结果:生成一个新的frame或者改变原frame,这种做法很危险,但此例只是为了展示其能被调用。one can define a str method for a class, which Python will call hen it needs a string to print. This method will be called with the object as the first argument and should return a str.
class Coordinate(object): def __init__(self, x, y): self.x = x self.y = y def __str__(self): return "<" + self.x + "," + self.y + ">" def distance(self, other): return math.sqrt(sq(self.x - other.x) + sq(self.y - other.y))c = Coordinate(6, 8)origin = Coordinate(0, 0)print(origin.distance(c))# origin.distance()里面不能直接指定一个tuple形式的坐标,因为程序找不到对应的x和y。>>> 10.0
4.1. time 与 self.time的区别
class Clock(object): def __init__(self, time): self.time = time def print_time(self): time = '6:30' # 若将此处改为self.time,则输出结果变为6:30 print(self.time) # 若将此处改为time,则输出结果变为6:30clock = Clock('5:30')clock.print_time()# 此例中可以理解为有两个变量,self.time和time,分别储存不同的值。
4.2. class中method的运行
class Clock(object): def __init__(self, time): self.time = time def print_time(self, time): print timeclock = Clock('5:30')clock.print_time('10:30')# 在第一次call Clock('5:30')时,相当于只运行了 __init__ 这个函数,赋值了此frame里的self.time。
4.3. 不同instance之间的aliasing关系
class Clock(object): def __init__(self, time): self.time = time def print_time(self): print(self.time)boston_clock = Clock('5:30')paris_clock = boston_clockparis_clock.time = '10:30'boston_clock.print_time()>>>10:30# boston_clock and paris_clock are two names for the same object. # 他们指向的是同一个对象# This is called aliasing.
4.4. x与self.x的再次区别
class Weird(object): def __init__(self, x, y): self.y = y self.x = x def getX(self): return x def getY(self): return yclass Wild(object): def __init__(self, x, y): self.y = y self.x = x def getX(self): return self.x def getY(self): return self.yX = 7Y = 8> w1 = Weird(X, Y)> print w1.getX()>>> name 'x' is not defined> w1 = Wild(X, Y)> print(w1.getX())>>> 7> w4 = Wild(X, 18)> print w4.getX()>>> 7# 因为class时是在定义,会先执行X,Y的赋值,才会有w4的赋值。> X = w4.getX() + w1.getX()# 改变X的值为14,然后再次调用w4.getX()> print w4.getX()>>> 7# 所以,改变的是全局变量X的值,而没有改变w4的frame中x的值。
4.5. 在一个类中添加equal和repr 两个method
class Coordinate(object):
def init(self, x, y): self.x = x self.y = ydef getX(self): # Getter method for a Coordinate object's x coordinate. # Getter methods are better practice than just accessing an attribute directly return self.xdef getY(self): # Getter method for a Coordinate object's y coordinate return self.ydef __str__(self): return '<' + str(self.getX()) + ',' + str(self.getY()) + '>'
Your task is to define the following two methods for the Coordinate class:
Add an __eq__ method that returns True if coordinates refer to same point in the plane (i.e., have the same x and y coordinate).Define __repr__, a special method that returns a string that looks like a valid Python expression that could be used to recreate an object with the same value. In other words, eval(repr(c)) == c given the definition of __eq__ from part
class Coordinate(object): def __init__(self,x,y): self.x = x self.y = y def getX(self): # Getter method for a Coordinate object's x coordinate. # Getter methods are better practice than just accessing an attribute directly return self.x def getY(self): # Getter method for a Coordinate object's y coordinate return self.y def __str__(self): return '<' + str(self.getX()) + ',' + str(self.getY()) + '>' def __eq__(self, other): return self.x == other.x and self.y == other.y def __repr__(self): return 'Coordinate(' + str(self.getX()) + ', ' + str(self.getY()) + ')'
**关于repr
class test: def __init__(self,name,age): self.age = age self.name = name t = test("Zhou",30) print(t)
以上代码的输出结果为“<main.test object at 0x000001FA117FEA58>”
print方法之所以能打印对应,正是由于每个类都有继承自object类的_repr_方法,在这里,print函数实际输出的是test对象_repr_方法的返回值,以下两行代码的结果是完全一致的:
print(t) print(t._repr_())
_repr_方法默认返回该对象实现类的“类名+object at +内存地址”值
当然,我们也可以尝试自己重写该方法,来满足我们希打印出的信息
class test: def __init__(self,name,age): self.age = age self.name = name def __repr__(self): return "Class_Test[name="+self.name+",age="+str(self.age)+"]" t = test("Zhou",30) print(t)
输出结果为:Class_Test[name=Zhou,age=30]
通过重写_repr_方法,我们打印出了类名、以及其包含的属性名称、属性值
———————————————— 版权声明:本文为CSDN博主「specialxj79」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/specialxj79/article/details/90389989**new type的三要素: behavior, internal data representation, interface
Create a new type to represent a set (or collection) of integers
– Initially the set is empty – A particular integer appears only once in a set----define the behavior– Internal data representation
– Interface
class intSet(object): """An intSet is a set of integers The value is represented by a list of ints, self.vals Each int in the set occurs in self.vals exactly once.""" def __init__(self): """Create an empty set of integers""" self.vals = [] def insert(self, e): """Assumes e is an integer and insert e into self""" if not e in self.vals: self.vals.append(e) def __str__(self): """Returns a string representation of self""" self.vals.sort() return '{' + ','.join([str(e) for e in self.vals]) + '}' def member(self, e): """Assumes e is an integer, Returns True if e is in self, and False otherwise""" return e in self.vals def remove(self, e): """Assumes e is an integer and removes e from self Raises ValueError if e is not in self""" try: self.vals.remove(e) except: raise ValueError(str(e) + ' not found')
special methods有时也叫magic methods,他们都是在python中原本内置过的函数,若在class中未特别定义,则会自动调用内置参数;若单独定义了,则调用class中的版本。
1. 打印用的函数__str__和__repr__
It’s common practice in Python to provide a string representation of your object for the consumer of your class (a bit like API documentation.) There are two ways to do this using dunder methods:
__repr__: The “official” string representation of an object. This is how you would make an object of the class. The goal of __repr__ is to be unambiguous.__str__: The “informal” or nicely printable string representation of an object. This is for the enduser.
Let’s implement these two methods on the Account class:
class Account:
# … (see above)def __repr__(self): return 'Account({!r}, {!r})'.format(self.owner, self.amount)def __str__(self): return 'Account of {} with starting amount: {}'.format( self.owner, self.amount)
If you don’t want to hardcode “Account” as the name for the class you can also use self.class.name to access it programmatically.
If you wanted to implement just one of these to-string methods on a Python class, make sure it’s repr.
2. 其他的一些special method
这个描述比较具体,但条理性一般
https://dbader.org/blog/python-dunder-methods这个条理清晰,比较全
https://rszalski.github.io/magicmethods/