Naming practice for objects of a class in Python - python

I have this weird problem as to how to name objects of a class.
For example, consider the class:
>>> class DoSomething:
pass
What should I call the object of this class? do_something or what? Since I came out of the learning stage, I used to use x, y or z or whatever came to my mind. But now since I am learning to write proper code and not the language, I always face this problem. Any suggestions?

Name it something representative of what it's actually being used for. For instance:
class Cereal:
def eat(self):
print 'yum'
breakfast = Cereal()
breakfast.eat()
or
class User:
def __init__(self, userid):
# ...
admin_user = User(ADMIN_ID)

You should name it after what it represents. For example if I have a class User in a web application and I want to refer to the currently logged-in user, I name the variable current_user.
And if you have more objects of one class, your approach fails immediately. Giving the variable an index like do_something1, do_something2 is not and will never be an option.
Use something meaningful, so that a reader of your code knows what this variable represents.
Btw. this applies to all programming languages, not just Python.

One good naming practise is to give plural names to collections such as sets and lists.

Related

How can I automatically update my class variables and lists using a child class? [duplicate]

Is there any way to make certain variables in classes "private" (or whatever self.__var really is) but be accessible to another class, like friends in c++, except in python? I do not want the variables in either class being messed with. Nor do I want to copy the entire code over and convert it for the second class.
No, there is not such an option.
Use names that start with single underscores and tell the other people working on your project to not be silly about what they access.
The philosophy of Python is that issues like access control are up to programmer discipline. It doesn't attempt to encode in the language which parts of the program are internal implementation details, and which are part of the documented interface. Thus, it doesn't need constructs like friend to try to declare which other parts of the program are part of the implementation of a class and which are merely clients.
The idea is that if you can't write/design/document/use good code without partially encoding these concepts into your program, you probably can't do it when you are encoding them either. Therefore it's better not to have such constructs in the language, since they don't increase the expressive power of the language and occasionally they get in the way.
there is no option of friend function in python.
you have an option to define a protected variable by using a single underscore,
but in python protected variable is also accessed by the main function, but this is not exactly the definition of a protected variable just have a look.
class Student:
_schoolName = 'XYZ School' # protected class attribute
def __init__(self, name, age):
self._name=name # protected instance attribute
self._age=age # protected instance attribute
std = Student("Swati", 25)
std._name
#answer is ->'Swati'
std._name = 'Dipa'
std._name
#answer is ->'Dipa'
I have no clue what you're talking about.
>>> class Foo(object):
... __bar = 42
...
>>> class Quux(object):
... def spam(self):
... print Foo._Foo__bar
...
>>> q = Quux()
>>> q.spam()
42

"Friend"ing classes in python

Is there any way to make certain variables in classes "private" (or whatever self.__var really is) but be accessible to another class, like friends in c++, except in python? I do not want the variables in either class being messed with. Nor do I want to copy the entire code over and convert it for the second class.
No, there is not such an option.
Use names that start with single underscores and tell the other people working on your project to not be silly about what they access.
The philosophy of Python is that issues like access control are up to programmer discipline. It doesn't attempt to encode in the language which parts of the program are internal implementation details, and which are part of the documented interface. Thus, it doesn't need constructs like friend to try to declare which other parts of the program are part of the implementation of a class and which are merely clients.
The idea is that if you can't write/design/document/use good code without partially encoding these concepts into your program, you probably can't do it when you are encoding them either. Therefore it's better not to have such constructs in the language, since they don't increase the expressive power of the language and occasionally they get in the way.
there is no option of friend function in python.
you have an option to define a protected variable by using a single underscore,
but in python protected variable is also accessed by the main function, but this is not exactly the definition of a protected variable just have a look.
class Student:
_schoolName = 'XYZ School' # protected class attribute
def __init__(self, name, age):
self._name=name # protected instance attribute
self._age=age # protected instance attribute
std = Student("Swati", 25)
std._name
#answer is ->'Swati'
std._name = 'Dipa'
std._name
#answer is ->'Dipa'
I have no clue what you're talking about.
>>> class Foo(object):
... __bar = 42
...
>>> class Quux(object):
... def spam(self):
... print Foo._Foo__bar
...
>>> q = Quux()
>>> q.spam()
42

Class Level Property for Django model in Python

I have a Django model storing some infrequently changed but often used data. I'm looking for a pattern so that I can refer to them as kind of static class variables, eg, like SomeModel.Bar or SomeModel.Baz.
At the moment I'm using a staticmethod like so:
class SomeModel(models.Model):
name = models.CharField(max_length=100)
#staticmethod
def Baz():
#retrieve from cache or lookup Baz item
return baz
Meaning I refer to the items as SomeModel.Baz() but this just doesn't quite feel right. I just get the impression that I'm doing something wrong. I don't want to make it a property, as I don't want an instance to refer to the item.
Can anyone point me at a pattern or example to show me is I can implement a class level property in this way? Or tell me why I should be doing something totally different? Thanks :).
If you want some logic for model which doesn't belong to particular row, write custom model manager.

Python grab class in class definition

I don't even know how to explain this, so here is the code I'm trying.
from couchdb.schema import Document, TextField
class Base(Document):
type = TextField(default=self.__name__)
#self doesn't work, how do I get a reference to Base?
class User(Base):
pass
#User.type be defined as TextField(default="Test2")
The reason I'm even trying this is I'm working on creating a base class for an orm I'm using. I want to avoid defining the table name for every model I have. Also knowing what the limits of python is will help me avoid wasting time trying impossible things.
The class object does not (yet) exist while the class body is executing, so there is no way for code in the class body to get a reference to it (just as, more generally, there is no way for any code to get a reference to any object that does not exist). Test2.__name__, however, already does what you're specifically looking for, so I don't think you need any workaround (such as metaclasses or class decorators) for your specific use case.
Edit: for the edited question, where you don't just need the name as a string, a class decorator is the simplest way to work around the problem (in Python 2.6 or later):
def maketype(cls):
cls.type = TextField(default=cls.__name__)
return cls
and put #maketype in front of each class you want to decorate that way. In Python 2.5 or earlier, you need instead to say maketype(Base) after each relevant class statement.
If you want this functionality to get inherited, then you have to define a custom metaclass that performs the same functionality in its __init__ or __new__ methods. Personally, I would recommend against defining custom metaclasses unless they're really indispensable -- instead, I'd stick with the simpler decorator approach.
You may want to check out the other question python super class relection
In your case, Test2.__base__ will return the base class Test. If it doesn't work, you may use the new style: class Test(object)

python classes that refer to each other

I have two classes that refer to each other, but obviously the compiler complains. Is there any way around this?
EDIT
Actually my code is slightly different than what Hank Gay uses. So python can definitely deal with some kinds of circular references, but it tosses an error in the following situation. Below is what I've got and I get an 'name Y not defined error'
class X(models.Model):
creator = Registry()
creator.register(Y)
class Y(models.Model):
a = models.ForeignKey(X)
b = models.CharField(max_length=200)
Hope this helps clarify. Any suggestions.
In python, the code in a class is run when the class is loaded.
Now, what the hell does that mean? ;-)
Consider the following code:
class x:
print "hello"
def __init__(self): print "hello again"
When you load the module that contains the code, python will print hello. Whenever you create an x, python will print hello again.
You can think of def __init__(self): ... as equivalent with __init__ = lambda self: ..., except none of the python lambda restrictions apply. That is, def is an assignment, which might explain why code outside methods but not inside methods is run.
When your code says
class X(models.Model):
creator = Registry()
creator.register(Y)
You refer to Y when the module is loaded, before Y has a value. You can think of class X as an assignment (but I can't remember the syntax for creating anonymous classes off-hand; maybe it's an invocation of type?)
What you may want to do is this:
class X(models.Model):
pass
class Y(models.Model):
foo = something_that_uses_(X)
X.bar = something_which_uses(Y)
That is, create the class attributes of X which reference Y after Y is created. Or vice versa: create Y first, then X, then the attributes of Y which depend on X, if that's easier.
Hope this helps :)
The error is that execution of creator.register(Y) is attempted during the (executable) definition of class X, and at that stage, class Y is not defined. Understand this: class and def are statements that are executed (typically at import time); they are not "declarations".
Suggestion: tell us what you are trying to achieve -- perhaps as a new question.
UPDATE: He changed the question after my answer. The currently accepted solution is better in light of the new question.
What are you saying is the problem?
class A(object):
def __init__(self):
super(A, self).__init__()
def b(self):
return B()
class B(object):
def __init__(self):
super(B, self).__init__()
def a(self):
return A()
This compiles and runs just fine.
As long as you are working within a method you can access the class object.
Thus the example above has no problems if creator.register(Y) is moved inside __init__. However, you cannot have circular references to classes outside of methods.
This is a great question. Although others have already answered it, I will feel free to provide another example.
Consider this program.
#dataclass
class A:
b: B
class B:
def __init__(self):
pass
b is now a class-level variable and this program does not work. The name B is not defined at the moment when the Python interpreter loads (executes) the code of class A. Unlike compiled languages (such as C/C++), interpreters execute the code from the beginning to the end of the file command by command, in one pass. Since Python needs to know what B is when it defines the class A, it fails. B is only defined later.
Now, consider a slightly different program.
class A:
def __init__(self):
self.b = B()
class B:
def __init__(self):
pass
b is now an object-level variable and this program works. Python still executes the code from the beginning to the end of the file in the single pass, however, now it does not need to know what B is at the moment it reads the self.b = B() line. This is because the __init__ method is executed only when someone wants to construct an object of class A. Since the construction of an object will happen somewhere later in the program (when B is already defined), __init__ will work fine when it is needed.
I came here late, but I want to show how I resolved this problem.
You can have a class nested to the other, and both classes will be able to reference each other
Here a demonstration:
class X():
class Y():
def x(self):
return X()
def y(self):
return self.Y()
a1 = X()
a2 = a1.y()
b1 = X.Y()
b2 = b1.x()
And you can create a BaseClass that contains the classes you want to referenciate
class Z():
class X():
def y(self):
return Z.Y()
class Y():
def x(self):
return Z.X()
As we well know, it looks like a self-evident contradiction that we try to imagine of two independent but inter-dependent entities just from a point of their birth in physical world. But, when it comes to the area of software, we often encounter this kind of issues so called 'circular or mutual references'. That may come more seriously in object-oriented design, in which inter-operating software elements are usually defined and related to one another in imitation of such a way as physical ones, but still as pure logical existences.
In many programming languages, these issues have been resolved by declaring to-be-referenced elements in time before their to-reference elements just in form of signatures (no body definitions) for functions or classes. However, that sort of evading tricks seems neither longer available nor useful for a script-based language like Python.
In Python, we'd better approach 'circular reference' in a view of software engineering, as follows:
It's much better to redesign classes not circular if possible; there are several ways (e.g. class de- or composition, call-back function, observer or subscriber patterns, and etc.) to make references between elements occur within the same class, removed or inverse.
In cases that linearizing some circular chains between elements might cause more serious problem in some aspect like quality or productivity, we can take another measure to separate their traditional construction phase into two: creating and structuring.
For example, two persons in friends who are destined to have their birth absolutely after observing the other's birth can do in a way that they are first born and then have their friendship just before any meaningful and observable occasions happen.
Note that if we face some extreme complexity or need some high degree of integrity in dealing with inter-aggregated objects, applying a Factory pattern will pay off.
The problem is most likely not Python. I would think it is an SQL issue. The classes are via an abstraction layer converted to an SQL query to create a table.
You are trying to reference from one table another one that at the time does not exist yet.
In SQL you would solve this by creating the table first without the references and after that modify them to make those references,
However I am not sure about my answer, so take it with lots of seasoning, I would be actually quite surprised if Django's database abstraction layer doesn't deal with cross references nicely.

Categories